Why the following works in ruby?

86 Views Asked by At

to_a over a range of integers behaves differently in this case. Upto 15 decimals, include? returns false but once it reached 16 decimals array considers the decimal digit as part of array.

Why?

2.2.1 :020 > (1..9).to_a.include?(8.999999999999999)
 => false 
2.2.1 :021 > (1..9).to_a.include?(8.9999999999999999)
 => true 
2.2.1 :022 >

And why range only says this is true

2.2.1 :001 > (1..9).include?(8.9)
 => true 
1

There are 1 best solutions below

3
spickermann On BEST ANSWER

(1..9).include?(8.9) is the same than 1 <= 8.9 && 8.9 <= 9. I think it is obvious why this returns true.

But (1..9).to_a returns the array [1,2,3,4,5,6,7,8,9]. This leads to the another observation:

8.999999999999999 == 9   #=> false
8.9999999999999999 == 9  #=> true

Floating point shenanigans.

You might want to use next_float to investigate the next representable floating-point number (as Tom Lord pointed out in the comments):

8.999999999999999.next_float   #=> 9.0
8.9999999999999999.next_float  #=> 9.000000000000002

Et voilà.