From: Rajinder Yadav Date: 2009-12-23T00:49:16+09:00 Subject: Re: integers and floats Paul Smith wrote: > On Tue, Dec 22, 2009 at 2:16 PM, Rajinder Yadav wrote: >> Paul Smith wrote: >>> On Tue, Dec 22, 2009 at 1:36 PM, Rajinder Yadav >>> wrote: >>>> Paul Smith wrote: >>>>> On Tue, Dec 22, 2009 at 1:01 PM, Rajinder Yadav >>>>> 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 :) >>>> 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? >> 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. 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. > >> 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? >> >>>>> 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 Yadav >>>>>> >>>>>> http://DevMentor.org >>>>>> >>>>>> Do Good! - Share Freely