2016-05-17 3 views
2

to_a по целому ряду целых чисел ведет себя по-другому в этом случае. UPTO 15 знаков после запятой, include? возвращает false, но как только он достиг 16 знаков после запятой массив считает десятичную цифру в качестве части массива.Почему в рубине работает следующее?

Почему?

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 > 

И почему диапазон только говорит, что это правда

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

'(1..9) .INCLUDE? (8.9)' то же самое, чем '1 <= 8.9 8.9 && <= 9'. Я думаю, что это понятно, почему это возвращает «истина». Но '(1..9) .to_a' возвращает массив' [1,2,3,4,5,6,7,8,9] '. Это приводит к вопросу, почему '8.9999999999999999 == 9' eval для' true', но '8.999999999999999 == 9' to' false'? Плавающие точки shenanigans ... – spickermann

+1

Еще один *** «почему не номера работают на языке х» *** вопрос. xd – ndn

+1

@spickermann, вы должны написать это как ответ. – ndn

ответ

4

(1..9).include?(8.9) является тем же, чем 1 <= 8.9 && 8.9 <= 9. Я думаю, это очевидно, почему это возвращает true.

Но (1..9).to_a возвращает массив [1,2,3,4,5,6,7,8,9]. Это приводит к другому наблюдению:

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

Floating point shenanigans.

Вы можете использовать next_float исследовать следующее представимое число с плавающей точкой (как Том Лорд указал в комментариях):

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

вуаля.

+3

Просто, чтобы добавить к этому - если вы используете рубин '' v2.2 +, вы можете использовать 'Float # next_float', чтобы помочь понять, что происходит:' (8,999999999999999) .next_float == 9,0; (8.9999999999999999) .next_float == 9.000000000000002' - Другими словами, '8.9999999999999999' буквально то же самое, что и' 9.0' в рубине. Такие ошибки округления с плавающей запятой НЕ характерны для рубина. –

+0

@TomLord Awesome! – spickermann

+0

Да это же, как и 9 при запуске 8.9999999999999999 на IRB его возвращения 9.0, но при запуске 8.999999999999999 возвращает 8.999999999999998 – Thorin