3

私はかなり環境に配慮したプログラマーであり、現在Pythonを学んでいます。私は「コンピュータ科学者のように考えることを学ぶ」(クラスとメソッド)の第17章までですが、完全には理解できない方法で失敗した最初のdoctestを書いたばかりです。

class Point(object):
    '''
    represents a point object.
    attributes: x, y
    '''

    def ___init___(self, x = 0, y = 0):
        '''
        >>> point = Point()
        >>> point.y
        0
        >>> point = Point(4.7, 8.2)
        >>> point.x
        4.7
        '''

        self.x = x
        self.y = y

の2番目のdoctestは__init__失敗し、4.7ではなく4.7000000000000002を返します。ただし、「print」ステートメントを使用してdoctestを次のように書き直すと、次のようになります。

>>> point = Point(4.7, 8.2)
>>> print point.x
4.7

正しく動作します。

そこで、Pythonがどのようにfloatを格納するかを読みました。そして、10進数のバイナリ表現のために、不一致の理由は、Pythonが4.7を1と0の文字列として格納するためです。 。

しかし、私が理解していないのは、「point.x」を呼び出すと4.7000000000000002が返され、「printpoint.x」を呼び出すと4.7が返される理由です。他にどのような状況で、Pythonは「印刷」の場合と同じように丸めることを選択しますか?この丸めはどのように機能しますか?これらの有効数字の末尾は、プログラミングのエラーにつながる可能性がありますか(明らかに、doctestの失敗は別として)?丸めに注意を払わないと、危険なあいまいさが生じる可能性がありますか?

これは10進数のバイナリ表現に関係しているので、これは実際には一般的なCSの問題であり、Pythonに固有の問題ではないと確信していますが、今私が本当に知っておく必要があるのは、具体的にはPythonプログラマー、関連する問題やバグの蔓延を回避します。

また、ボーナスポイントについては、「a = 4.7」のような行によってアクティブ化されるデフォルト以外に、Pythonが浮動小数点数を格納できる他の方法はありますか?Decimalパッケージがあることは知っていますが、それがどのように機能するかは完全にはわかりません。正直なところ、この動的型付けのすべてが私を混乱させることがあります。

編集: Python 2.6を使用していることを指定する必要があります(ある時点でNumPyとBiopythonを使用したい)

4

5 に答える 5

4
>>> point.x

関数reprよりも多くの技術情報を保持する文字列表現用の関数を呼び出します。str

>>> print point.x

発生する

于 2010-08-22T17:53:27.693 に答える
3

これは、コンピューターが浮動小数点数を格納する方法と関係があります。これの詳細な説明はここにあります。ただし、あなたの場合、簡単な解決策は、の印刷された表現ではpoint.xなく、point.xに等しいかどうかをチェックすること4.7です。それで...

>>> point = Point(4.7, 8.2)
>>> point.x == 4.7
True

またはそれ以上:

>>> point = Point(4.7, 8.2)
>>> eps = 2**-53 #get epsilon for standard double precision number
>>> -eps <= point.x - 4.7 <= eps
True

eps浮動小数点演算の丸め誤差の最大値はどこにありますか。イプシロンの詳細については、こちらをご覧ください

編集: -eps <= point.x - 4.7 <= epsと同等abs(point.x - 4.7) <= epsです。誰もがPythonの比較演算子の連鎖に精通しているわけではないため、これを追加するだけです。

編集2: numpyについて言及したので、numpyには、自分で計算せずにepsを取得する方法があります。numpyを使用している場合は、eps = numpy.finfo(float).eps代わりに使用してください。numpyイプシロンは、何らかの理由で本来よりも大きく、ではなく2**-53に等しいことに注意してください。なぜなのかわかりません。2**-522**-53

于 2010-08-22T16:32:04.740 に答える
2

浮動小数点数を操作する場合、一般的なアプローチは次のようになります。

a == b if abs(a-b) <= eps, where eps is the required precision.

プログラミングコンテストでは、解決すべき問題とともにepsが提供されます。私のアドバイスは、あなたが自分のものに必要な精度を確立し、それを使用することです

于 2010-08-22T16:31:30.620 に答える
1

print数値を切り捨てるため、異なる動作が発生します。

In [1]: 1.23456789012334
Out[1]: 1.23456789012334 
In [2]: print 1.23456789012334
1.23456789012

Pythonのfloatで使用される精度で:

In [3]: 4.7 == 4.7000000000000002
Out[3]: True

これは、浮動小数点数が実数を表すために有限数の(2進数)桁を使用するため、浮動小数点数の(相対的な)精度が制限されるためです。したがって、上記のように、与えられた数値の異なる10進表現は、最も近いfloatで近似された後、Pythonでは実際に等しくなる可能性があります。これは浮動小数点数の一般的なプロパティです。

于 2010-08-22T16:28:46.803 に答える
1

この包括的なガイドでは、すべてを説明しています。

ここでは、Python 固有の説明を示します。

于 2010-08-22T17:21:14.057 に答える