# Integers and floats

Can someone explain to me why Ruby treats integers and floating point
numbers differently?

irb(main):069:0> 12.equal? 12
=> true

irb(main):071:0> 12.0.equal? 12.0
=> false

Kind Regards,
Rajinder Y.

http://DevMentor.org

Do Good! - Share Freely

On Tue, Dec 22, 2009 at 9:01 PM, Rajinder Y. [email protected]
wrote:

Can someone explain to me why Ruby treats integers and floating point
numbers differently?

irb(main):069:0> 12.equal? 12
=> true

irb(main):071:0> 12.0.equal? 12.0
=> false

ri Object#equal?

try eg,

x=12.0
=> 12.0
x.equal? x
=> true

kind regards -botp

On Tue, Dec 22, 2009 at 1:01 PM, Rajinder Y. [email protected]
wrote:

Can someone explain to me why Ruby treats integers and floating point
numbers differently?

irb(main):069:0> 12.equal? 12
=> true

irb(main):071:0> 12.0.equal? 12.0
=> false

Because they’re different

With .equal you’re checking to see whether 2 objects are in fact the
same object. 12, a Fixnum, is an immediate object, meaning all the
12s in your code are in fact the exact same object.

12.0, a floating point number, is constructed from scratch each time
you refer to it. So the 12.0 on the left is a separate construction
from the the 12.0 on the right.

irb(main):008:0> 12.object_id
=> 25
irb(main):009:0> a = 12
=> 12
irb(main):010:0> b = 12
=> 12
irb(main):011:0> a.object_id
=> 25
irb(main):012:0> b.object_id
=> 25

All of these 12’s are the same object.

irb(main):013:0> 12.0.object_id
=> 11121408
irb(main):014:0> a = 12.0
=> 12.0
irb(main):015:0> b = 12.0
=> 12.0
irb(main):016:0> a.object_id
=> 11187424
irb(main):017:0> b.object_id
=> 10954912

All of these 12.0s are different objects

irb(main):018:0> 12 == 12
=> true
irb(main):019:0> 12.0 == 12.0
=> true

But all of the 12.0s have the same value.

The same distinction happens for symbols and strings:

irb(main):020:0> “abc”.equal? “abc”
=> false
irb(main):021:0> :abc.equal? :abc
=> true

Kind Regards,
Rajinder Y.

http://DevMentor.org

Do Good! - Share Freely

Paul S.

[email protected]

On Tuesday 22 December 2009, Rajinder Y. wrote:

|Can someone explain to me why Ruby treats integers and floating point
|numbers differently?
|
|irb(main):069:0> 12.equal? 12
|=> true
|
|irb(main):071:0> 12.0.equal? 12.0
|=> false

equal? returns true if two objects are the same, that is if they have
the same
object_id. Integers represented by the Fixnum class are created only
once: if
I write
x = 123456
y = 123465
ruby will create an instance of class Fixnum representing the number
123456 in
the first line, but in the second line it doesn’t create a new one and
simply
uses the one which already exists. This is the same thing which happens
for
symbols.

On the other hand, the same doesn’t happen for objects of class Float:
here a
different instance is created every time:
x = 123.456
y = 123.456
produces two different objects representing the same floating point
number.
You can check this looking at the object_id of the different objects.

I hope this helps

Stefano

Paul S. wrote:

Because they’re different
thanks, I understand the object_id

my question is why is 12.0 constructed each time and 12 is immediate?
does it have to do with the fact that floats are simply binary
approximation.

=> 25

Do Good! - Share Freely

Kind Regards,
Rajinder Y.

http://DevMentor.org

Do Good! - Share Freely

On Tue, Dec 22, 2009 at 1:36 PM, Rajinder Y. [email protected]
wrote:

irb(main):071:0> 12.0.equal? 12.0
=> false

Because they’re different

thanks, I understand the object_id

my question is why is 12.0 constructed each time and 12 is immediate? does
it have to do with the fact that floats are simply binary approximation.

I’m not sure how you would make floating point numbers immediate.

Fixnums can be immediate by a clever trick with the object_id. This
is done presumably for performance - application deal with small
integers all the time.

Is anything else an immediate object in this sense?

Symbols aren’t immediate, but they have been made (presumbaly through
some kind of symbol table lookup) such that every :abc is the same
symbol.

I don’t think anything else works this way either, symbols have a
particular use case that is different to strings, and Ruby can play
with both.

Could you make floats work the same way as symbols? Probably. Is it
worth it? Under what use case is it important that all 12.0s be the
exact same object?

irb(main):008:0> 12.object_id
All of these 12’s are the same object.
=> 10954912
The same distinction happens for symbols and strings:

http://DevMentor.org
Kind Regards,
Rajinder Y.

http://DevMentor.org

Do Good! - Share Freely

Paul S.

[email protected]

Paul S. wrote:

irb(main):071:0> 12.0.equal? 12.0
is done presumably for performance - application deal with small
with both.

Could you make floats work the same way as symbols? Probably. Is it
worth it? Under what use case is it important that all 12.0s be the
exact same object?

I don’t know how Ruby makes integers immediate or why this is not
possible with floats. So to answer your use case question, the only use
case I see is the same one for integer. Efficiency of not having to
create new objects each time.

However I am going to assume trying to make floats immediate is less
efficient than creating new objects? or is there another reason floats
are treated the way they are in Ruby?

On Dec 22, 2009, at 11:03 AM, Paul S. wrote:

On Tue, Dec 22, 2009 at 2:16 PM, Rajinder Y. [email protected] wrote:

I have no idea what, if anything, has the object_ids 0, and 2.

Pretty easy: false and true.

irb(main):001:0> true.object_id
=> 2
irb(main):002:0> false.object_id
=> 0

Regards,
Florian G.

On Tue, Dec 22, 2009 at 2:16 PM, Rajinder Y. [email protected]
wrote:

Can someone explain to me why Ruby treats integers and floating point
thanks, I understand the object_id

Could you make floats work the same way as symbols? Probably. Is it
worth it? Under what use case is it important that all 12.0s be the
exact same object?

I don’t know how Ruby makes integers immediate or why this is not possible
with floats. So to answer your use case question, the only use case I see is
the same one for integer. Efficiency of not having to create new objects
each time.

Fixnums are immediate in MRI (Matz’s Ruby Interpreter) by using odd
numbered object_ids. The Fixnum 0 is represented by the object_id 1.
1 had id 3, 2 has id 5, 3 has id 7.

nil has the object_id 4.

I have no idea what, if anything, has the object_ids 0, and 2.

Bignums (integers past a certain size) don’t fit in this scheme (too
big to store in the object_id) so are constructed separately. AFAIK
no other object type uses the object_id trick to made Fixnum’s
immediate. This may be different in other Ruby implementations. It’s
entirely feasible that a Ruby implementation exists which does not
make Fixnum’s immediate.

I think that if you understand how Fixnum’s (and nil) are made
immediate, you realise that it’s hard to coerce other object types,
like Floats, into this scheme.

12.0, a floating point number, is constructed from scratch each time
=> 25
=> 12.0
=> true

Kind Regards,
Rajinder Y.

http://DevMentor.org

Do Good! - Share Freely

Paul S.

[email protected]

2009/12/22 Paul S. [email protected]:

=> true

I’m not sure how you would make floating point numbers immediate.

Well, you could - but at the expense of dramatically increased memory
need for every Ruby program because a standard float needs more bytes
to store than an int and so every object reference would have to be
significantly larger.

Fixnum-assignment”.

Fixnums can be immediate by a clever trick with the object_id. This
is done presumably for performance - application deal with small
integers all the time.

It’s rather the other way round: making Fixnums immediate is the
clever trick and Fixnum’s object_id is a derivative of that trick.

Is anything else an immediate object in this sense?

AFAIK nil, true, false.

exact same object?
I don’t think it’s worthwhile because at any point in time there are
not many float instances with the same value other than in artificial
test cases. The price to pay (memory, see above) is just too high.

Kind regards

robert

On Tue, Dec 22, 2009 at 2:42 PM, Florian G. [email protected]
wrote:

=> 2
irb(main):002:0> false.object_id
=> 0

Hah, of course. Obvious in retrospect, but I was so surprised to see
that nil wasn’t 0

Regards,
Florian G.

Paul S.

[email protected]

2009/12/22 Florian G. [email protected]:

=> 2
irb(main):002:0> false.object_id
=> 0

You need to know but there is a way that works without oracle turing
machine:

irb(main):005:0> 10.times {|i| printf “%4d %p\n”, i,
ObjectSpace._id2ref(i) rescue nil}
0 false
1 0
2 true
3 1
4 nil
5 2
7 3
9 4
=> 10

Kind regards

robert

Robert K. wrote:

=> 0
5 2
7 3
9 4
=> 10

Kind regards

robert

Robert thanks for the code snippet, that is so cool =) … more stuff to

Kind Regards,
Rajinder Y.

http://DevMentor.org

Do Good! - Share Freely

On Dec 22, 2009, at 11:19 AM, Robert K. wrote:

irb(main):001:0> true.object_id
2 true

robert

I didn’t use oracle turing machine, I only used irb to validate my
pre-existing knowledge.

But thanks for the trick :-).

Regards,
Florian

2009/12/22 Florian G. [email protected]:

ObjectSpace._id2ref(i) rescue nil}

I didn’t use oracle turing machine, I only used irb to validate my pre-existing knowledge.

See, that’s exactly what I meant.

But thanks for the trick :-).

You’re welcome.

Cheers

robert

Paul S. wrote:

irb(main):069:0> 12.equal? 12
I’m not sure how you would make floating point numbers immediate.

each time.
big to store in the object_id) so are constructed separately. AFAIK
no other object type uses the object_id trick to made Fixnum’s
immediate. This may be different in other Ruby implementations. It’s
entirely feasible that a Ruby implementation exists which does not
make Fixnum’s immediate.

I think that if you understand how Fixnum’s (and nil) are made
immediate, you realise that it’s hard to coerce other object types,
like Floats, into this scheme.

Thanks Paul for the explanation, it’s immediately obvious (now) how
immediate ids are assigned (no pun intended). I got a deeper
appreciation & understanding for Ruby.