[REBOL] Re: SKIP with *very* large values
From: tomc:darkwing:uoregon at: 16-May-2002 21:36
the 'Why' has to do with how numbers of different sizes are represented
by machines.
for regular everyday integers not "far" from zero the computer uses a
fixed number of bits to represent it, independent of the number of bits
required to express the number, typicaly 16,32 or 64 bits with 32 being
most common now.
example using 8 bits:
101 is five represented in binary using three bits
00000101 is five represented in binary using eight bits (just as 005 = 5)
any number from 0 to (2^8 - 1) can be represented in these eight bits
or 256 distinct values (this would be called an "unsigned integer").
however this does not allow for negative integers
So the first bit (leftmost) can be reserved as a negative flag)
in which case
10000101 is negative five represented in binary using eight bit integer
in this case we have 7 bits to represent the value or 0 thru (2^7 - 1)
and -2^7 (this would be called a "signed integer")
on the (64 bit) machine I am sitting at I can find the cutoff point where
a value is to large to fit in a rebol integer which is appearently 32
bits.
>> (power 2 31) - 1
== 2147483647
>> type? 2147483647
== integer!
>> type? 2147483648
== decimal!
>> type? -2147483647
== integer!
>> type? -2147483648
== decimal!
>>
>> to-integer 2147483648
** Math Error: Math or number overflow
** Where: to-integer
** Near: to integer! :value
so numbers <= -2^31 or >= 2^31 must be expressed differently
a simplified floating point number scheme is to take those same 32 bits
keep the first one as the sign flag the next 8 as a signed exponent (e)
and the remaining 23 as a "normalized" base (b)
where b is between 1 and 2
so the 32 bits as a floating point number can _approximate_ values
in the (+/-)2^((+/-)2^7) range or numbers with 38 or 39 decimal digits
to make the aproximation point clear:
>> 99999999999999999999 = 99999999999999999998
== true
even tho it is easy to see they are not equal as integers
rebols decimals! seem larger than standard 32 bit floating point and
smaller than standard 64 bit floating point so I'm really not sure how
they are represented.
but it is clear that skip should not accept values which are not discrete
unit steps.
i.e.
>> skip foo 3.14159
is hard to make sense of (like half a hole or a little bit pregnant)
when you ask for
>> skip foo 99999999999999999999
you are also asking for
>> skip foo 99999999999999999998.323322
because they _are_ the same decimal! value
so I do not think it is a bug that skip returns nonsense when it gets
nonsense but the doc could indicate non-integer numbers! are invalid
as arguments.
aside:
if you were wondering just how big a decimal! gets ...
>> big: copy "" loop 64 [append big "9"]
== {9999999999999999999999999999999999999999999999999999999999999999}
>> type? load big
== decimal!
>> append big "1"
== {99999999999999999999999999999999999999999999999999999999999999991}
>> type? load big
** Syntax Error: Invalid integer --
99999999999999999999999999999999999999999999999999999999999999991
** Near: (line 1)
99999999999999999999999999999999999999999999999999999999999999991
more than the 39 places for a 32 bit float
and far less than the 308 places of a 64 bit float
On Thu, 16 May 2002, Volker Nitsch wrote: