Python Infinity-警告はありますか?


179

したがって、Pythonには正と負の無限大があります。

float("inf"), float("-inf")

これは、注意が必要なタイプの機能のようです。知っておくべきことはありますか?


25
定数1e309はと解釈され+inf-1e309と解釈されることに注意してください-inf
Chris Taylor

回答:


97

それでも、次のような単純な算術から非数(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静かにあなたの計算に注入された値を。


8
単純な浮動小数点の加算、乗算などはinfを喜んで生成します:f = 1.3407807929942597e + 154; f * f => inf。OverflowErrorを送出することは、**の例外のようです。
エレゴン2015年

@エレゴンは、実際に**は少しバギーのようです。実数でオーバーフローするとエラーがスローされますが、オペランドのいずれかがinfまた-infはの場合は、0.0またはを返しますinf。したがって、入力が無限大の場合は正しく機能しますが、結果が無限大になる場合は正しく機能しません。
アベル

2
@Abelそれはバギーではありません。オーバーフローは、数が非常に大きいことを意味します。それを表現するには大きすぎますが、それでも無限よりはるかに小さいです。このような場所に無限大を置くことは、特定のアプリケーションロジックの例外ハンドラーには役立つかもしれませんが、Pythonでは一般的に正しくありません。
Lutz Prechelt 2016年

6
@Lutzそれが乗算として現れる場合、それはまだ一貫性のない動作です。確かにbig * bigも無限ではありません。
Richard Rast

100

Pythonの実装は、ガイダンスとして使用できるIEEE-754標準にかなり準拠していますが、コンパイルされた基礎となるシステムに依存しているため、プラットフォームの違いが発生する可能性があります。最近¹、「無限大」と「INF」を可能にする修正が適用されました、ここではそれほど重要ではありません。

以下のセクションは、IEEE浮動小数点演算を正しく実装するすべての言語に等しく適用されます。これは、Pythonだけに固有のものではありません。

不平等の比較

無限大およびより大きい>か小さい<演算子を処理する場合、次のことが重要です。

  • を含む任意の数+inf-inf
  • を含む任意の数-inf+inf
  • +infある高も低くもないよりも、+inf
  • -inf より高くも低くもない -inf
  • 関係する比較NaNはすべてfalse(infより高くも低くもないNaN

平等の比較

等しいかどうかを比較、場合+inf+inf同じである、などである-inf-inf。これは非常に議論されている問題であり、議論の余地があるように思われるかもしれませんが、IEEE標準にあり、Pythonはそのように動作します。

もちろん、+infはに等しくなく-infNaNそれ自体を含むすべてがに等しくありません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.powpowたり**、意図したとおりに動作しないため、注意が必要です。2つの実数の結果が高すぎて倍精度浮動小数点数に収まらない場合(無限を返す必要がある)、オーバーフロー例外がスローされますが、入力がinfまたはの場合-inf、正しく動作し、infまたはを返します0.0。2番目の引数がの場合、最初の引数がでない限り、NaNが返されます。他にも問題があり、すべてがドキュメントでカバーされているわけではありません。NaN1.0
  • math.expと同じ問題がありmath.powます。これをオーバーフローに対して修正する解決策は、次のようなコードを使用することです。

    try:
        res = math.exp(420000)
    except OverflowError:
        res = float('inf')

ノート

注1:追加の警告として、IEEE標準で定義されているように、計算結果がアンダーフローまたはオーバーフローした場合、結果はアンダーまたはオーバーフローエラーではなく、正または負の無限大:になり1e308 * 10.0ますinf

注2:NaN戻り値を伴う計算とそれ自体を含むNaNとの比較はであるため、関数を使用して、数値が本当にそうであるかどうかを判断する必要があります。NaNNaNfalsemath.isnanNaN

注3: Pythonは書き込みをサポートしていますがfloat('-NaN')NaN内部にはサインオンが存在しないため、サインは無視されます。を除算する-inf / +infと、結果はNaNになります-NaN(そういうものはありません)。

注4: Pythonは、コンパイル対象のCまたはJavaライブラリに依存しており、基盤となるすべてのシステムがこの動作をすべて正しく実装しているわけではないため、上記のいずれかに依存するように注意して。確認したい場合は、計算を行う前に無限大をテストしてください。

¹)最近のバージョン3.2以降を意味します。
²)フローティングポイントは、正と負のゼロをサポートしているので:x / float('inf')その符号と続け-1 / float('inf')利回り-0.01 / float(-inf)利回り-0.01 / float('inf')利回り0.0及び-1/ float(-inf)歩留まりを0.0。また、0.0 == -0.0istrueである場合は、サインをtrueにしたくない場合は手動でチェックする必要があります。


11
小さなnitpick:無限の収量を無限大となく、すべての計算:-1 * float('infinity') == -inf
エヴァン・クラール

4
それが私がそれが小さなひっくり返しだと言った理由です。無限大で作業しているときはサインが完全に無視されるのではないかと心配していて、他の人のために説明したかったのです。
エヴァン・クラール

12
まあ、ほぼ:1 / float( 'infinity')== 0.0
Phil

3
@Phil:infを使用したすべての計算がinfまたはNaNになるわけではないことを示すつもりだったと確信していますが、コメントを読んでいる可能性のある他の人にその1 / float( 'infinity ')== 0.0はtrueです。なぜなら、あなたが無限に近づいているとき、除算の結果は0に近づきます。私はそれが単なる基本的な計算であることを知っていますが、私はそれらの読書が理解できるようにしたか、少なくとも理由について手がかりを持っていることを望んでいました。結果はそれが何であるかです。
Anthony Pace、

1
この答えは、受け入れられた答えよりもはるかに優れていると感じています。
クリスチャンヘレンツ2016年

3

C99も同様です。

最近のすべてのプロセッサで使用されているIEEE 754浮動小数点表現には、正の無限大(sign = 0、exp =〜0、frac = 0)、負の無限大(sign = 1、exp =〜0、frac = 0)用に予約されたいくつかの特別なビットパターンがあります。 )、そして多くのNaN(非数:exp =〜0、frac≠0)。

心配する必要があるのは、一部の算術は浮動小数点の例外/トラップを引き起こす可能性があることですが、これらはこれらの「興味深い」定数だけに限定されません。


1
それで、私の算術が大きすぎると、それがinfになる可能性がありますか?
Casebash 2009年

@Casebashいいえ、それはを引き起こしますOverflowError
wizzwizz4

2

これまで誰も言及していない警告を見つけました。それが実際の状況で頻繁に現れるかどうかはわかりませんが、ここでは完全を期すためです。

通常、無限大を法とする数値を計算すると、それ自体が浮動小数点として返されますが、無限大を法とする小数が返されます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で確認できます

更新:これはPython 3.8修正されます。


2

非常に悪い警告: ゼロによる除算

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

慎重に!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.