web-dev-qa-db-ja.com

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

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

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

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

172
Casebash

infを含む単純な算術演算から、非数(NaN)値を取得することもできます。

>>> 0 * float("inf")
nan

通常not通常の算術計算で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値を例外からすぐに知ることをお勧めします。

96
Greg Hewgill

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

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

不平等の比較

無限大および>より大きい演算子または<より小さい演算子を扱う場合、以下がカウントされます。

  • +infを含む任意の数が-infよりも大きい
  • -infを含む任意の数が+infよりも小さい
  • +inf+infよりも 高くも低くもない
  • -inf-infよりも高くも低くもない
  • NaNを含む比較はすべて偽です(infNaNよりも高くも低くもありません)

平等の比較

等しいかどうかを比較すると、+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.powpow、または**の使用は、本来の動作をしないため、注意が必要です。 2つの実数の結果が高すぎて倍精度浮動小数点数に収まらない場合(無限大を返す必要があります)、オーバーフロー例外をスローしますが、入力がinfまたは-infの場合、正しく動作し、infまたは0.0を返します。 2番目の引数がNaNの場合、最初の引数が1.0でない限り、NaNを返します。すべての がdocs でカバーされているわけではありませんが、さらに問題があります。
  • math.expには、math.powと同じ問題があります。これをオーバーフロー用に修正する解決策は、次のようなコードを使用することです。

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

ノート

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

注2: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')-0.0を生成し、1 / float(-inf)-0.0を生成し、1 / float('inf')0.0および-1/ float(-inf)を生成し、0.0を生成します。さらに、 0.0 == -0.0true であるため、trueにしたくない場合は手動で記号を確認する必要があります。

99
Abel

C99 も同様です。

最新のすべてのプロセッサで使用されるIEEE 754浮動小数点表現には、正の無限大(sign = 0、exp =〜0、frac = 0)、負の無限大(sign = 1、exp =〜0、frac = 0 )、および多くのNaN(非数:exp =〜0、frac≠0)。

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

3
ephemient

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

通常、無限大を法とする数値を計算すると浮動小数点数として返されますが、無限大を法とする小数部は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
Elias Zamaria