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で割っただけです。正確である必要があります。

4

5 に答える 5

3

これは典型的な浮動小数点の丸めです。Floatの固定ビット数ですべての10進数を表現することはできないため、一部の値は表現可能な最も近い値に丸められます。

このため、フロートの同等性を比較しないことをお勧めします。より小さいかより大きいかを比較しますが、完全に等しいことはありません。

http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding

簡単に言うと、「正確でなければならない」というわけではありません。浮動小数点の小数からそれを期待しないでください。

于 2009-08-18T21:12:40.667 に答える
2

浮動小数点演算へようこそ。標準の浮動小数点表記では表現できず、ほんの少しずれた数値がたくさんあります。

これは次のように簡単に説明できます。

(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

数値が大きくなるほど、小数点以下の精度が低くなることに注意してください。これは、数値全体を表すために使用できる精度が固定されているためです。

于 2009-08-18T21:14:42.707 に答える
1

フローティングポイントは正確ではありません。短いバージョンでは、有限量のビットに無限量の値を格納することはできません。

長いバージョンは、すべてのコンピューター科学者が浮動小数点演算について知っておくべきことです

于 2009-08-18T21:13:12.007 に答える
0

これは、すべての浮動小数点数を正確に表すことができないためです。

于 2009-08-18T21:12:05.240 に答える