Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[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: