web-dev-qa-db-ja.com

pythonの負のゼロ

Pythonからの出力で負のゼロに遭遇しました。たとえば、次のように作成されます。

k = 0.0
print(-k)

出力は-0.0になります。

ただし、-kと0.0を比較して等しいと、Trueになります。 0.0-0.0の間に違いはありますか(おそらく、それらが異なる内部表現を持っていることは気にしません。プログラムでのそれらの動作のみを気にします。)知っておくべき隠されたトラップはありますかの?

49
max

チェックアウト: ウィキペディアの0(数値)

基本的に、IEEEは実際には負のゼロを定義します

そして、すべての目的のためのこの定義によって:

-0.0 == +0.0 == 0

-0.0と+0.0は異なるオブジェクトであることをaaronasterlingに同意します。それらを等価にする(等価演算子)ことで、コードに微妙なバグが導入されないようにします。 a * b == c * dと考えてください

>>> a = 3.4
>>> b =4.4
>>> c = -0.0
>>> d = +0.0
>>> a*c
-0.0
>>> b*d
0.0
>>> a*c == b*d
True
>>> 

[編集:コメントに基づく詳細情報]

私がすべての実用的な目的で言ったとき、私は言葉を急いで選びました。私は標準的な平等比較を意味しました。

この点について、さらに情報と参照を追加します。

(1)参考文献に記載されているように、IEEE標準では、-0 <+0ではなく+0 = -0となるように比較が定義されています。常にゼロの符号を無視することは可能ですが、IEEE標準はそうしません。乗算または除算に符号付きゼロが含まれる場合、通常の符号規則が回答の符号の計算に適用されます。

Divmod、atan2などの操作はこの動作を示します。実際、atan2は、基礎となる「C」libと同様に、IEEE定義に準拠しています。定義については、リファレンス#2を参照してください。

>>> divmod(-0.0,100)
(-0.0, 0.0)
>>> divmod(+0.0,100)
(0.0, 0.0)

>>> math.atan2(0.0, 0.0) == math.atan2(-0.0, 0.0)
True 
>>> math.atan2(0.0, -0.0) == math.atan2(-0.0, -0.0)
False

1つの方法は、実装がIEEEの動作に準拠しているかどうかをドキュメントで確認することです。また、プラットフォームの微妙なバリエーションもあるようです。

この側面(IEEE定義への準拠)は、どこでも尊重されてはいません。無関心によるPEP 754(#3)の拒否をご覧ください!これが後で取り上げられたかどうかはわかりません。

参照:

  1. http://docs.Sun.com/source/806-3568/ncg_goldberg.html#924
  2. FPTAN http://en.wikipedia.org/wiki/Atan2
  3. http://www.python.org/dev/peps/pep-0754/
29
pyfunc

atan2() 関数に違いがあります(少なくとも一部の実装では)。私のPython 3.1および3.2 on Windows(これは、基礎となるC実装に基づいており、注記CPython実装の詳細によれば、 Python math module documentation )の下部:

>>> import math
>>> math.atan2(0.0, 0.0)
0.0
>>> math.atan2(-0.0, 0.0)
-0.0
>>> math.atan2(0.0, -0.0)
3.141592653589793
>>> math.atan2(-0.0, -0.0)
-3.141592653589793
15
Craig McQueen

math.copysign() は、奇妙なプラットフォームでPython=を実行していない限り、_-0.0_と_+0.0_の扱いが異なります。

_math._copysignxy
xyの符号付きで返します。符号付きゼロをサポートするプラットフォームでは、copysign(1.0, -0.0)は_-1.0_を返します。

_>>> import math
>>> math.copysign(1, -0.0)
-1.0
>>> math.copysign(1, 0.0)
1.0
_
13
Alex Trebek

はい、0.0と-0.0の間には違いがあります(Pythonでは再現できません:-P)。正の数を0.0で割ると、正の無限大になります。その同じ数を-0.0で割ると、負の無限大になります。

それ以外では、2つの値の間に実際的な違いはありません。

11

同じ値で異なる数値

>>> Decimal('0').compare(Decimal('-0'))        # Compare value
Decimal('0')                                   # Represents equality

>>> Decimal('0').compare_total(Decimal('-0'))  # Compare using abstract representation
Decimal('1')                                   # Represents a > b

参照 :
http://docs.python.org/2/library/decimal.html#decimal.Decimal.comparehttp://docs.python.org/2 /library/decimal.html#decimal.Decimal.compare_total

1
user