Reputation: 8058
The following expression evaluated to true on Ruby 1.9:
31964252037939931209 == 31964252037939933000.0
# => true
but I have no clue how this is happening. Am I missing something here?
Upvotes: 0
Views: 300
Reputation:
The explanation is simply that standard methods for representing floating-point (i.e. decimal) numbers on computers are inherently inaccurate and only ever provide an approximate representation. This is not specific to Ruby; errors of the type you show in your question crop up in virtually every language and on every platform and you simply need to be aware they can happen.
Trying to convert the large integer value in your example to floating-point illustrates the problem a little better—you can see the interpreter is unable to provide an exact representation:
irb(main):008:0> 31964252037939931209.to_f
=> 31964252037939933000.0
Wikipedia's article on floating point has a more thorough discussion of accuracy problems with further examples.
Upvotes: 4
Reputation: 80065
Ruby used to convert bignums to floats in such comparisons, and in the conversion precision was lost. The issue is solved in more recent versions.
Upvotes: 1
Reputation: 4633
Here you can see the source code of the comparer for Ruby:
http://www.ruby-doc.org/core-1.9.3/Comparable.html#method-i-3D-3D
And seems to be using this actual comparer:
https://github.com/p12tic/libsimdpp/blob/master/simdpp/core/cmp_eq.h
The methood seems to be comparing using this:
/** Compares 8-bit values for equality.
@code
r0 = (a0 == b0) ? 0xff : 0x0
...
rN = (aN == bN) ? 0xff : 0x0
@endcode
@par 256-bit version:
@icost{SSE2-AVX, NEON, ALTIVEC, 2}
*/
My guess might be that the value is the same for both numbers.
Upvotes: 0