したがって、Pythonには正と負の無限大があります。
float("inf"), float("-inf")
これは、いくつかの注意が必要なタイプの機能のように思えます。知っておくべきことはありますか?
Pythonの実装はIEEE-754標準に非常によく準拠しており、ガイダンスとして使用できますが、コンパイルされた基盤となるシステムに依存しているため、プラットフォームの違いが発生する可能性があります。最近¹、 「無限大」と「無限大」を許可する修正が適用されましたが、ここではそれほど重要ではありません。
次のセクションは、IEEE浮動小数点演算を正しく実装するすべての言語に同様に当てはまります。Pythonだけに固有のものではありません。
無限大および大なり小なり演算子を処理>
する<
場合、次のことが重要になります。
+inf
が-inf
-inf
が+inf
+inf
高くも低くもない+inf
-inf
高くも低くもない-inf
NaN
はすべて偽です(inf
高くも低くもありませんNaN
)等しいかどうかを比較すると、とは等しく、+inf
と+inf
は等しく-inf
なり-inf
ます。これは非常に議論の余地のある問題であり、物議を醸すように聞こえるかもしれませんが、IEEE標準であり、Pythonはそのように動作します。
もちろん、+inf
は等しくなく、それ自体-inf
を含むすべてのものはに等しくありません。NaN
NaN
両方のオペランドが無限大でない限り、無限大を使用したほとんどの計算では無限大が生成されます。演算の除算またはモジュロ、またはゼロを使用した乗算では、次の点に注意してください。
NaN
0.0
または-0.0
²になります。NaN
。inf - inf
と、結果は未定義になりますNaN
。inf - -inf
と、結果はinf
;になります。-inf - inf
と、結果は-inf
;になります。-inf - -inf
と、結果は未定義になりますNaN
。inf + inf
と、結果はinf
;になります。inf + -inf
と、結果は未定義になりますNaN
。-inf + inf
と、結果は未定義になりますNaN
。-inf + -inf
と、結果はになり-inf
ます。math.pow
、pow
または**
動作しないため、注意が必要です。2つの実数の結果が高すぎて倍精度浮動小数点数に収まらない場合(無限大を返す必要があります)、オーバーフロー例外をスローしますが、入力がまたはの場合、正しく動作し、またはのいずれかをinf
返します。2番目の引数が。の場合、最初の引数が。でない限り、を返します。さらに多くの問題がありますが、すべてがドキュメントでカバーされているわけではありません。-inf
inf
0.0
NaN
NaN
1.0
math.exp
と同じ問題が発生しmath.pow
ます。オーバーフローに対してこれを修正する解決策は、次のようなコードを使用することです。
try:
res = math.exp(420000)
except OverflowError:
res = float('inf')
注1:追加の警告として、IEEE標準で定義されているように、計算結果がアンダーまたはオーバーフローした場合、結果はアンダーエラーまたはオーバーフローエラーではなく、正または負の無限大に1e308 * 10.0
なりますinf
。
注2: returnを使用した計算、およびそれ自体を含むとの比較はであるため、関数を使用して、数値が実際にであるかどうかを判断する必要がありNaN
ます。NaN
NaN
NaN
false
math.isnan
NaN
注3: Pythonは書き込みをサポートしていますが、内部float('-NaN')
にサインオンが存在しないため、サインは無視されます。NaN
除算-inf / +inf
すると、結果はNaN
ではなく、になります-NaN
(そのようなことはありません)。
注4: Pythonはコンパイル対象のCまたはJavaライブラリに依存しており、基盤となるすべてのシステムがこの動作をすべて正しく実装しているわけではないため、上記のいずれかに依存するように注意してください。確認したい場合は、計算を行う前に無限大をテストしてください。
¹)最近はバージョン3.2以降を意味します。
²)浮動小数点は正と負のゼロをサポートするため、次のようになります。x / float('inf')
符号と-1 / float('inf')
yields -0.0
、1 / float(-inf)
yields -0.0
、1 / float('inf')
yields 0.0
、 yieldsを保持し-1/ float(-inf)
ます0.0
。さらに、それを真にしたくない場合は、手動で符号を確認する必要があります0.0 == -0.0
。true
以下を含む単純な算術から、非数(NaN)値を取得できますinf
。
>>> 0 * float("inf")
nan
通常、通常の算術計算では値を取得できないことに注意してください。inf
>>> 2.0**2
4.0
>>> _**2
16.0
>>> _**2
256.0
>>> _**2
65536.0
>>> _**2
4294967296.0
>>> _**2
1.8446744073709552e+19
>>> _**2
3.4028236692093846e+38
>>> _**2
1.157920892373162e+77
>>> _**2
1.3407807929942597e+154
>>> _**2
Traceback (most recent call last):
File "<stdin>", line 1, in ?
OverflowError: (34, 'Numerical result out of range')
このinf
値は、異常なセマンティクスを持つ非常に特殊な値と見なされるため、計算に値を黙って注入するOverflowError
のではなく、例外をすぐに把握することをお勧めします。inf
C99もそうです。
最新のすべてのプロセッサで使用されているIEEE754浮動小数点表現には、正の無限大(sign = 0、exp =〜0、frac = 0)、負の無限大(sign = 1、exp =〜0、frac = 0)用に予約されたいくつかの特別なビットパターンがあります。 )、および多くのNaN(数値ではない:exp =〜0、frac≠0)。
心配する必要があるのは、一部の演算によって浮動小数点の例外/トラップが発生する可能性があることですが、これらはこれらの「興味深い」定数だけに限定されません。
これまで誰も言及していない警告を見つけました。実際の状況で頻繁に発生するかどうかはわかりませんが、ここでは完全を期すためです。
通常、無限大を法とする数を計算すると、それ自体が浮動小数点数として返されますが、無限大を法とする分数はnan
(数ではなく)返されます。次に例を示します。
>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan
Pythonバグトラッカーに問題を報告しました。https://bugs.python.org/issue32968で見ることができます。
更新:これはPython3.8で修正される予定です。
非常に悪い警告: ゼロ除算
ほんの少しでは、それ1/x
までx = 1e-323
ですinf
が、いつx = 1e-324
または少し投げますZeroDivisionError
>>> 1/1e-323
inf
>>> 1/1e-324
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero
だから注意してください!