[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Parsing numbers
Date: Fri, 29 Sep 89 09:13:53 pdt
From: hall@CTC.FMC.COM (David Hall)
I was trying to read some numbers on a MacIvory (Genera 7.4) and
noticed some peculiar behavior. I got the same results on a 3640
running 7.2. (In the following examples the LET form was evaled,
the number after ON was entered and the thing after the -> was
returned. (TYPE-OF *) yielded the thing after the ,)
The most error-free way to be sure of parsing strings into integers is with
PARSE-INTEGER rather than READ.
For example, (parse-integer "1111" :radix 2) -> 15
(parse-integer "1191" :radix 2) -> Error: Garbage character 9
seen while parsing
integer in "1191".
(parse-integer "123" :radix 16) -> 291
(parse-integer "1A3" :radix 16) -> 419
If you have to use READ (e.g., you're parsing floating-point or rational
numbers), use the variables SI:*READ-EXTENDED-IBASE-UNSIGNED-NUMBER* and
SI:*READ-EXTENDED-IBASE-SIGNED-NUMBER*. Here is the documentation string for
the former:
(documentation 'SI:*READ-EXTENDED-IBASE-UNSIGNED-NUMBER* 'variable) ->
"Controls how a token that could be a number or a symbol, and does not start
with a + or - sign, is interpreted when IBASE is greater than ten.
NIL => it is never a number.
T => it is always a number.
:SHARPSIGN => it is a symbol at top level, but a number after #X or #nR.
:SINGLE => it is a symbol except immediately after #X or #nR."
The default for these variables are :SINGLE and :SHARPSIGN, respectively,
which means that #X(+a small #xface in a -bad place) reads as
(10 SMALL 64206 IN A -2989 PLACE).
You can say
(let ((*read-base* 16)
(si:*read-extended-ibase-unsigned-number* t)
(si:*read-extended-ibase-signed-number* t))
(read))
and if the next thing in the stream is (a small face in a bad place), the thing
which is returned is (10 SMALL 64206 IN 10 2989 PLACE).
About your second example:
I guess this next example is OK in a perverse way, i.e. it would be
correct if 9 were a binary digit with value 8 greater than 1.
(let ((*read-base* 2)) (read)) on 1191 -> 31 , FIXNUM
I've always considered this behaviour to be a bug, but it's been that way
since Maclisp. The Common Lisp manual doesn't say whether this is allowed,
forbidden, or neither.