On 6/4/06, Aaron Patterson <aaron_patterson / speakeasy.net> wrote:
> Hi everyone.  I'm porting some C code to pure ruby, and I would like to
> keep Ruby from turning my numbers in to Bignums.  Is that possible?
>
> For example, in C:
>
>   printf("number: %d\n", 0xd76aa478);
>
> Prints "number: -680876936"
>
> In ruby:
>
> irb(main):001:0> puts 0xd76aa478
> 3614090360
> => nil
>
> Is it possible to get ruby to behave the same way as C?  This seems like
> something easy to do, I'm just having a hard time figuring it out.
> Thank you!

Hi Aaron,

Short answer, no. In Ruby, as you know, everything is an object and in
the C code implementing ruby, this is represented by pointers to these
objects. These pointers have a type of VALUE which is basically a
32-bit integer. But it would be pretty inefficient to store integers
as memory-allocated objects so instead it stores them in the same
32-bit integer. (This is true for FixInt, BigNum is an object ref). So
how does the interpreter know the difference between an object
reference and a FixInt? It relies on the fact that all memory pointers
are are on 4 or 8-byte boundaries so that leaves at least the last 2
bits free. These last two bits are used to specify whether VALUE is an
integer, a refence or possibly a symbol, true or false value or nil.
This means that there are only 30 bits left to specify the value of
FixInt. So the maximum value you can store in a FixInt is 0x3FFFFFFF
and the minimum is -0x40000000.

irb(main):007:0> 0x40000000.class
=> Bignum
irb(main):008:0> 0x3fffffff.class
=> Fixnum
irb(main):009:0> -0x40000000.class
=> Fixnum
irb(main):010:0> -0x40000001.class
=> Bignum

Hope that makes sense.

Cheers,
Dave

> --Aaron
>
>
>