2016-05-17 9 views
2

to_aは、この場合、さまざまな整数の動作をします。 小数点以下15桁まで、include?falseを返しますが、16小数点以下の配列に到達すると小数点は配列の一部と見なされます。なぜ以下はRubyで動作するのですか?

なぜですか?

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)?(8.9)'は '1 <= 8.9 && 8.9 <= 9'と同じです。これがなぜ真実を返すのかは明らかです。しかし '(1..9).to_a'は配列' [1,2,3,4,5,6,7,8,9] 'を返します。これはなぜ '8.9999999999999999 == 9 'が' true'に評価されるのか、 '8.999999999999999 == 9'が' false'になるのかという疑問につながりますか?浮動小数点数の不定詞... – spickermann

+1

さらに別の*** "数字は言語xで動作しません" ***質問。 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 

のEt出来上がり。

+3

これを追加するだけです。あなたがruby 'v2.2 +'を使っていると仮定すると、 'Float#next_float'を使って何が起こっているのかを理解するのに役立ちます。'(8.999999999999999).next_float == 9.0; (8.9999999999999999).next_float == 9.000000000000002' - 言い換えれば、 '8.9999999999999999'は文字通り、rubyの' 9.0'と同じです。このような浮動小数点丸め誤差は、ルビ固有のものではありません。 –

+0

@TomLord素晴らしい! – spickermann

+0

はい、それは8.999999999999999を返すときに8.9999999999999999を実行したときと同じですが、8.999999999999999を実行すると、8.999999999999998を返します。 – Thorin

関連する問題