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.
Do Good! - Share Freely
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.
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
=> trueirb(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
=> trueirb(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.Do Good! - Share Freely
–
Paul S.
http://www.nomadicfun.co.uk
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.
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
=> falseBecause 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.Do Good! - Share Freely
–
Paul S.
http://www.nomadicfun.co.uk
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_idCould 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.Do Good! - Share Freely
–
Paul S.
http://www.nomadicfun.co.uk
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.
Plase see also the other current thread “Ruby’s implementation of
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.
http://www.nomadicfun.co.uk
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
=> 10Kind regards
robert
Robert thanks for the code snippet, that is so cool =) … more stuff to
add to my notes!
–
Kind Regards,
Rajinder Y.
Do Good! - Share Freely
On Dec 22, 2009, at 11:19 AM, Robert K. wrote:
irb(main):001:0> true.object_id
2 truerobert
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.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs