これは私には非常に奇妙です:
irb(main):012:0> "100.7".to_f.modulo(1)
=> 0.700000000000003
なぜ最後に3?
irb(main):019:0> "10.7".to_f.modulo(1)
=> 0.699999999999999
ここでも同じです...この値の余りを1で割っただけです。正確である必要があります。
これは私には非常に奇妙です:
irb(main):012:0> "100.7".to_f.modulo(1)
=> 0.700000000000003
なぜ最後に3?
irb(main):019:0> "10.7".to_f.modulo(1)
=> 0.699999999999999
ここでも同じです...この値の余りを1で割っただけです。正確である必要があります。
これは典型的な浮動小数点の丸めです。Floatの固定ビット数ですべての10進数を表現することはできないため、一部の値は表現可能な最も近い値に丸められます。
このため、フロートの同等性を比較しないことをお勧めします。より小さいかより大きいかを比較しますが、完全に等しいことはありません。
http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding
簡単に言うと、「正確でなければならない」というわけではありません。浮動小数点の小数からそれを期待しないでください。
浮動小数点演算へようこそ。標準の浮動小数点表記では表現できず、ほんの少しずれた数値がたくさんあります。
これは次のように簡単に説明できます。
(1..10).collect do |i|
v = ((10**i).to_f + 0.7)
puts "%13.1f = %.30f" % [ v, v.modulo(1) ]
end
結果は次のとおりです。
10.7 = 0.699999999999999289457264239900
100.7 = 0.700000000000002842170943040401
1000.7 = 0.700000000000045474735088646412
10000.7 = 0.700000000000727595761418342590
100000.7 = 0.699999999997089616954326629639
1000000.7 = 0.699999999953433871269226074219
10000000.7 = 0.699999999254941940307617187500
100000000.7 = 0.700000002980232238769531250000
1000000000.7 = 0.700000047683715820312500000000
10000000000.7 = 0.700000762939453125000000000000
数値が大きくなるほど、小数点以下の精度が低くなることに注意してください。これは、数値全体を表すために使用できる精度が固定されているためです。
フローティングポイントは正確ではありません。短いバージョンでは、有限量のビットに無限量の値を格納することはできません。
これは、すべての浮動小数点数を正確に表すことができないためです。