Forum: Ruby Bignum-Fixnum-Numeric confusion

Posted by Pritam Dey (pritamdey)
on 2013-03-06 12:52
Hi,

I am newbie to Ruby.

But couldn't properly understand which rules in Ruby decides the below
object's when any number comes to it?

`Bignum` `Fixnum` `Numeric` `Integer`.

I am basically from `C` background. So these many classification making
me confused.

Sorry for my English, It's horrible I know :)


Thanks in advance for your help!
Pritam
Posted by Adam Prescott (Guest)
on 2013-03-06 13:10
(Received via mailing list)
Say you're on a 64-bit system. In that case, any numbers with absolute
value less than 2^62 will be a Fixnum:

>> (2**62 - 1).class
=> Fixnum

Fixnums are usually described as "immediate" values. In MRI at least,
their value is encoded in their object ID using 2n+1:

>> (-2..2).map { |e| [e, e.object_id] }
=> [[-2, -3], [-1, -1], [0, 1], [1, 3], [2, 5]]

Anything greater than or equal to 2^62 in absolute value will come out
as a Bignum, which are "normal" instances of the Bignum class.

>> (2**62).class
=> Bignum

There's no such object ID stunt here:

>> (0..4).map { |e| [(2**62 + e), (2**62 + e).object_id] }
=> [[4611686018427387904, 70120613511800], [4611686018427387905,
70120613511580], [4611686018427387906, 70120613511360],
[4611686018427387907, 70120613511140], [4611686018427387908,
70120613510920]]

(For n-bit systems, Fixnum values are stored with n-1 bits since 1 bit
is used by the VM, so the range of values for a Fixnum is (-2^(n-1) +
1, 2^(n-1) - 1). Not sure if this is exactly the same with other Ruby
implementations.)

Integer is the superclass of both, for cases where you wish to simply
reason about integers:

>> Bignum.ancestors
=> [Bignum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
>> Fixnum.ancestors
=> [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]

Numeric is to cover Integers and other types of number:

>> Float.ancestors
=> [Float, Numeric, Comparable, Object, Kernel, BasicObject]

For example, Complex in the stdlib mathn library is a subclass of 
Numeric:

>> require "mathn"
=> true
>> Complex(2, 5)
=> (2+5i)
>> Complex.ancestors
=> [Complex, Numeric, Comparable, Object, Kernel, BasicObject]

Hope that helps!
Posted by Hans Mackowiak (hanmac)
on 2013-03-06 13:12
Numeric General Class for all of them
 - Integer: your int type in C (base class for the other two)
    - FixNum : they are stored as bitshift, so 2.object_id == 
2.object_id
    - BigNummer to big to store as bitshift, so they are real objects 
with different object_ids

Fixnum: (10**18).object_id == (10**18).object_id #=> true
Bignum: (10**19).object_id == (10**19).object_id #=> false


Float, Complex and Rational are other Numeric classes
Posted by Pritam Dey (pritamdey)
on 2013-03-06 13:37
@Hans thanks for your care.

Please find the below I am getting something different in my IRB:

I am using the below Ruby version.

ruby 1.9.3p374 (2013-01-15) [i386-mingw32]

>> (10**18).object_id == (10**18).object_id
=> false
>> (10**19).object_id == (10**19).object_id
=> false
Posted by Hans Mackowiak (hanmac)
on 2013-03-06 13:48
its because of your 32 bit architecture

so i think
(10**9).object_id == (10**9).object_id #returns true
(10**10).object_id == (10**10).object_id #returns false

for you?
Posted by Ryan Davis (Guest)
on 2013-03-06 13:56
(Received via mailing list)
You're on a 32 bit system so your cutoff is lower. Use 2**29 for 
example.

You can see the size of a fixnum with 0.size
Posted by Pritam Dey (pritamdey)
on 2013-03-06 14:00
From the doc: http://ruby-doc.org/core-1.9.3/Fixnum.html

I found the below features :

Fixnum:

(a) Fixnum objects have immediate value. This means that when they are 
assigned or passed as parameters, the actual object is passed, rather 
than a reference to that object. - Can the same be shown in IRB. Hope 
then only it will be correctly understood by me.

(b) Assignment does not alias Fixnum objects. - What does it actually 
then?

(c) "There is effectively only one Fixnum object instance for any given 
integer value, so, for example, you cannot add a singleton method to a 
`Fixnum`." - Couldn't understand the reason of not to add the 
`singleton` method with Fixnum object instances.

-- the above (b) and (c) points are also made me confused.
Posted by Hans Mackowiak (hanmac)
on 2013-03-06 14:13
(c) because in C an Fixnum is only an bitshift ...
    other ruby objects are struct RObject objects ... in this RObject 
there are flags and options and entries for instance variables and 
singleton methods


so there is no space where this stuff could be defined in a Fixnum

(in 1.9 it was possible to define instance variables into Fixnums but 
this was dropped in 2.0)
Posted by Robert Klemme (robert_k78)
on 2013-03-06 14:50
(Received via mailing list)
On Wed, Mar 6, 2013 at 2:00 PM, Pritam Dey <lists@ruby-forum.com> wrote:
> From the doc: http://ruby-doc.org/core-1.9.3/Fixnum.html
>
> I found the below features :
>
> Fixnum:
>
> (a) Fixnum objects have immediate value. This means that when they are
> assigned or passed as parameters, the actual object is passed, rather
> than a reference to that object. - Can the same be shown in IRB. Hope
> then only it will be correctly understood by me.

The fact that Fixnums are "immediate values" is just an implementation
detail.  From the perspective of a user of the language it does not
make a functional difference (this is about performance only). I
suggest you take a different route and start with basic understanding
of how numeric classes and general OO and variables work in Ruby.

> (b) Assignment does not alias Fixnum objects. - What does it actually
> then?

From a logical point of view it does:

irb(main):001:0> a = 1
=> 1
irb(main):002:0> a.class
=> Fixnum
irb(main):003:0> b = a
=> 1
irb(main):004:0> b.class
=> Fixnum
irb(main):005:0> a == b
=> true
irb(main):006:0> a.equal? b
=> true
irb(main):007:0> a.object_id == b.object_id
=> true

> (c) "There is effectively only one Fixnum object instance for any given
> integer value, so, for example, you cannot add a singleton method to a
> `Fixnum`." - Couldn't understand the reason of not to add the
> `singleton` method with Fixnum object instances.

I think the reasoning is flawed: the fact that there is only one
instance of every Fixnum does by no means prevent associating
singleton methods with the instance.  For example, it's still possible
to store instance variables in a Fixnum instance:

# same a and b as above
irb(main):009:0> a.instance_variable_set '@x', "yeah!"
=> "yeah!"
irb(main):010:0> a.instance_variables
=> [:@x]
irb(main):011:0> a.instance_variable_get '@x'
=> "yeah!"
irb(main):012:0> b.instance_variables
=> [:@x]
irb(main):013:0> b.instance_variable_get '@x'
=> "yeah!"
irb(main):014:0> 1.instance_variable_get '@x'
=> "yeah!"
irb(main):015:0> 2.instance_variable_get '@x'
=> nil

It's just an implementation decision to not allow singleton methods for 
Fixnum.

> -- the above (b) and (c) points are also made me confused.

As I said above.  For understanding when Ruby will switch between
types (your original question, as I understand it) this is irrelevant.
 If you want to understand how that works (method #coerce is central
to that) you can read my blog post which describes how to create a
class which adheres to the conventions of operator overloading and
doing math in Ruby:
http://blog.rubybestpractices.com/posts/rklemme/01...

Kind regards

robert
Posted by Hans Mackowiak (hanmac)
on 2013-03-06 15:02
Robert Klemme wrote in post #1100376:

>> (c) "There is effectively only one Fixnum object instance for any given
>> integer value, so, for example, you cannot add a singleton method to a
>> `Fixnum`." - Couldn't understand the reason of not to add the
>> `singleton` method with Fixnum object instances.
>
> I think the reasoning is flawed: the fact that there is only one
> instance of every Fixnum does by no means prevent associating
> singleton methods with the instance.  For example, it's still possible
> to store instance variables in a Fixnum instance:
>

i need to resay that this is not possible in 2.0 anymore ... so you dont 
should depend on it
Posted by Robert Klemme (robert_k78)
on 2013-03-06 16:27
(Received via mailing list)
On Wed, Mar 6, 2013 at 3:02 PM, Hans Mackowiak <lists@ruby-forum.com> 
wrote:
>> to store instance variables in a Fixnum instance:
>
> i need to resay that this is not possible in 2.0 anymore ... so you dont
> should depend on it

I didn't say it's a good idea. :-)

Cheers

robert
Posted by Pritam Dey (pritamdey)
on 2013-03-06 16:37
Great Thanks to you guys:

Just need to stuck myself from two more areas.

From the same doc:

(a) While Fixnum values are immediate, Bignum objects are not — 
assignment and parameter passing work with references to objects, not 
the objects themselves. - Actually as far as I know we are passing the 
references to the objects,not the actual objects. But here I couldn't 
follow the taste.

(b)When a calculation involving Bignum objects returns a result that 
will fit in a Fixnum, the result is automatically converted. - In `C` I 
found some rules such automatic conversions. But does the same 
applicable here also or other rules defined here specially for Ruby?


(c)For the purposes of the bitwise operations and [], a Bignum is 
treated as if it were an infinite-length bitstring with 2’s complement 
representation. - Why so?

Thanks for all of your collaborative help to understand this nice 
concept in Ruby.

Thanks,
Pritam
Posted by Robert Klemme (robert_k78)
on 2013-03-06 17:24
(Received via mailing list)
On Wed, Mar 6, 2013 at 4:37 PM, Pritam Dey <lists@ruby-forum.com> wrote:
> follow the taste.
See earlier

> (b)When a calculation involving Bignum objects returns a result that
> will fit in a Fixnum, the result is automatically converted. - In `C` I
> found some rules such automatic conversions. But does the same
> applicable here also or other rules defined here specially for Ruby?

See ealier

> (c)For the purposes of the bitwise operations and [], a Bignum is
> treated as if it were an infinite-length bitstring with 2s complement
> representation. - Why so?

Because it's the most reasonable thing to do when dealing with binary
numbers of arbitrary number of bits.

Cheers

robert
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.