Why is 0x7FFFFFFF Bignum and not Fixnum?


#1

According to the Pickaxe book :
“A Fixnum holds Integer values that can be represented in a native
machine word (minus 1 bit). If any operation on a Fixnum exceeds this
range, the value is automatically converted to a Bignum.”

In IRB :

0x3FFFFFFF.class
=> Fixnum

0x3FFFFFFF.size
=> 4
As expected, this comfortably fits into 32 bits, but so should this :

0x7FFFFFFF.class
=> Bignum

0x7FFFFFFF.size
=> 4

  1. Why has it gone to Bignum ? it shouldn’t do this until 0x80000000.
  2. Interestingly, BigNum has recognised it fits into 32 bits, but it was
    upsized anyway !

I’m trying to do some performance critical bit manipulations (without
leaving ruby) and this means I’ll be using BigNum unnecessarily.

Regards

Magpie


#2

In message removed_email_address@domain.invalid, Mr Magpie
writes:

0x3FFFFFFF.class
=> Fixnum

0x3FFFFFFF.size
=> 4
As expected, this comfortably fits into 32 bits, but so should this :

0x7FFFFFFF.class
=> Bignum

0x7FFFFFFF.size
=> 4

  1. Why has it gone to Bignum ? it shouldn’t do this until 0x80000000.

Because 0x40000000 is either the sign bit or the magic flag. I don’t
know
how Ruby does that part, but that’s what I’d expect. There’s no
“unsigned” types here.

-s


#3

Because 0x40000000 is either the sign bit or the magic flag.

0x80000000 would be the sign bit. What is this “magic flag” that seems
to be occupying 0x40000000 ?


#4

In message removed_email_address@domain.invalid, Mr Magpie
writes:

Because 0x40000000 is either the sign bit or the magic flag.

0x80000000 would be the sign bit. What is this “magic flag” that seems
to be occupying 0x40000000 ?

Remember how it said you get “32 bits, minus one”?

What that means is you have a total of 31 bits available for values.

So. The largest 31-bit number is 0x7FFF,FFFF. But wait! What about
negative numbers? How do we represent those? If we are using a 31-bit
representation, then the topmost of those 31 bits must be the sign
bit, so the highest number is 0x3FFF,FFFF – because 0x7FFF,FFFF is
negative.

Unless something else similar is being done; I never read the source. I
just know that, if you have 31 bits available for positive and negative
numbers, you can’t represent 0x7FFF,FFFF as a positive number in that
range, and Ruby seems to have no unsigned types.

-s


#5

unknown wrote:

In message removed_email_address@domain.invalid, Mr Magpie
writes:

Because 0x40000000 is either the sign bit or the magic flag.

0x80000000 would be the sign bit. What is this “magic flag” that seems
to be occupying 0x40000000 ?

Remember how it said you get “32 bits, minus one”?

What that means is you have a total of 31 bits available for values.

Oh, right!

So. The largest 31-bit number is 0x7FFF,FFFF. But wait! What about
negative numbers? How do we represent those? If we are using a 31-bit
representation, then the topmost of those 31 bits must be the sign
bit, so the highest number is 0x3FFF,FFFF – because 0x7FFF,FFFF is
negative.

Unless something else similar is being done; I never read the source. I
just know that, if you have 31 bits available for positive and negative
numbers, you can’t represent 0x7FFF,FFFF as a positive number in that
range, and Ruby seems to have no unsigned types.

Oh really, thats kinda sad - the abstractions are getting in the way…


#6

On 4/30/07, Mr Magpie removed_email_address@domain.invalid wrote:

Because 0x40000000 is either the sign bit or the magic flag.

0x80000000 would be the sign bit. What is this “magic flag” that seems
to be occupying 0x40000000 ?

This is kind of “hack” / implementation detail:

this bit is a flag that distinguishes between immediate values and
full objects.
the number is either


#7

From: “Mr Magpie” removed_email_address@domain.invalid

range, and Ruby seems to have no unsigned types.

Oh really, thats kinda sad - the abstractions are getting in the way…

I think I’ve missed unsigned ints in ruby about as often as I’ve ever
missed unsigned floats. :wink:

If you really need fast 32-bit unsigned int manipulation, possibly
RubyInline
might be of use?

http://www.zenspider.com/ZSS/Products/RubyInline/

HTH,

Bill


#8

On 4/30/07, Gary W. removed_email_address@domain.invalid wrote:

This point of view makes assignment and parameter passing semantics
consistent regardless of what objects are being referenced.

Gary W.

Thanks, your explanation seems clearer.


#9

Thanks for the informative answers. I see the reasoning now.

Has anyone done performance comparisons of Fixnum and Bignum ?


#10

On Apr 30, 2007, at 9:58 AM, Jano S. wrote:

This is kind of “hack” / implementation detail:

this bit is a flag that distinguishes between immediate values and
full objects.

This is another of my attempts to kill the ‘immediate value’ meme
in Ruby. Feel free to ignore.

I think Ruby’s semantics are clearer if you consider that the only
‘values’ in the language are references. These values reference
objects but the objects themselves are not manipulated as values
by the language.

Some references indicate implicit objects (nil, false, true,
fixnums, and symbols) and some references indicate explicit objects
(everything else). This differentiation is mostly an
implementation detail.

This point of view makes assignment and parameter passing semantics
consistent regardless of what objects are being referenced.

Gary W.