浮動小数点モジュロ問題
-
22-09-2019 - |
質問
非常に奇妙なバグに遭遇しました。コード内のコメントを読んで、バグの内容を正確に確認してください。ただし、基本的に、1 を法とする変数は 1 を返します (ただし、1 には等しくありません!)。浮動小数点が 1 に非常に近いものの、正確には一致しないという表示の問題があると思います。ただし、ゼロにモジュロする必要があります。(last % 1) != 1.0 ! であるため、このケースを簡単にテストすることはできません。同じ番号を別の Python ターミナルに接続してみると、すべてが正しく動作します。どうしたの?
def r(k,i,p):
first = i*p
last = first + p
steps = int((i+1)*p) - int(i*p)
if steps < 1:
return p
elif steps >= 1:
if k == 0:
return 1 - (first % 1)
elif k == steps:
if i == 189:
print last, 1, type(last), last % 1, last - int(last)
# Prints: 73.0 1 <type 'float'> 1.0 1.0
print last % 1 == 1 # Returns False
if last % 1 == 1.0:
return 0
return (last % 1)
else:
return 1
解決
IEEE754へようこそ、滞在を楽しむます。
他のヒント
repr()
を使用することができますように、印刷は、番号の完全な精度を示していません
>>> last=72.99999999999999
>>> print last, 1, type(last), last % 1, last - int(last)
73.0 1 <type 'float'> 1.0 1.0
>>> print last % 1 == 1
False
>>> print repr(last), 1, type(last), repr(last%1), repr(last - int(last))
72.999999999999986 1 <type 'float'> 0.99999999999998579 0.99999999999998579
>>>
あなたはmath.fmod(x、y)を使用する必要があります。ここで http://docs.python.org/library/math.html:
"Pythonの式は、x%yは、同じ結果を返さないことに注意してくださいC規格の意図はそのFMOD(x、y)が正確に(数学的に、無限の精度)であるが - にYをN * Xに等しいですいくつかの整数のn結果は以下ABSよりX及び大きさ(Y)。PythonのX%Y戻る代わりに、yの符号付きの結果と同じ符号を有し、フロート引数の正確に計算可能ではないかもしれないように、例えば、FMOD (-1E-100、1e100)は-1E-100であるが、Pythonの-1E-100%1e100は1e100-1e-100、正確floatとして表すことができないで、そして驚くべき1e100へのラウンドの結果整数を扱うときのPythonのx%yが好ましいが、フロートを扱う際する。このため、関数FMOD()が一般的に好ましい。 "
あなたは代わりにlast % 1
の math.fmod の機能を試すことができ、多分それは、より良いあなたの問題に適しています。
それとも、整数空間であなたの問題を定式ことができます。
とにかく、それが原因でも==
ようseemigly些細な事業からの不正確な結果に、平等の0.1 + 0.2 == 0.3
演算子を使用して浮動小数点値を比較することをお勧めではありません。