1

私は非常に奇妙なバグに遭遇しました。コード内のコメントを読んで、バグが正確に何であるかを確認しますが、基本的に1を法とする変数は1を返します(ただし、1とは等しくありません!)。フロートが1に非常に近いが、正確ではないという表示の問題があると思います。ただし、ゼロに変調する必要があります。(最後の%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
4

5 に答える 5

6

IEEE754へようこそ、ご滞在をお楽しみください

于 2010-02-24T02:35:05.270 に答える
6

印刷では、保存されている数値の完全な精度が表示されません。これを使用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
>>> 
于 2010-02-24T02:53:34.000 に答える
3

math.fmod(x、y)を使用する必要があります。これがhttp://docs.python.org/library/math.htmlからの抜粋です:

「Python式x%yは同じ結果を返さない場合があることに注意してください。C標準の目的は、fmod(x、y)が正確に(数学的に;無限の精度で)ある整数nに対してx --n*yに等しいことです。結果の符号がxと同じで、大きさがabs(y)未満になるようにします。Pythonのx%yは、代わりにyの符号の結果を返し、float引数に対して正確に計算できない場合があります。たとえば、fmod(-1e -100、1e100)は-1e-100ですが、Pythonの-1e-100%1e100の結果は1e100-1e-100であり、これは浮動小数点数として正確に表すことはできず、驚くべき1e100に丸められます。このため、関数浮動小数点数を操作する場合はfmod()が一般的に推奨されますが、整数を操作する場合はPythonのx%yが推奨されます。」

于 2010-02-24T12:47:00.033 に答える
1

の代わりにmath.fmod関数を試すこともできますがlast % 1、問題に適している可能性があります。または、整数空間で問題を再定式化することもできます。

とにかく、等式演算子を使用してfloat値を比較することはお勧めできません。これは、==次のような些細な操作でも結果が不正確になるためです。0.1 + 0.2 == 0.3

于 2010-02-24T08:33:34.170 に答える
0

任意精度が必要な場合は、それを実行するプロジェクトがいくつかあります。gmpyは、多精度整数、非常に見栄えのするmpmath 、およびMPFRをラップするbigfloatを処理します。あなたが持っているものは、gnibblerの答えで十分かもしれませんが、念のために。

于 2010-02-24T03:02:53.827 に答える