[英]Python Infinity - Any caveats?
So Python has positive and negative infinity: 因此,Python具有正负无穷大:
float("inf"), float("-inf")
This just seems like the type of feature that has to have some caveat. 这似乎就像必须要注意的功能类型。 Is there anything I should be aware of?
有什么需要我注意的吗?
Python's implementation follows the IEEE-754 standard pretty well, which you can use as a guidance, but it relies on the underlying system it was compiled on, so platform differences may occur. Python的实现很好地遵循了IEEE-754标准 ,您可以将其用作指导,但是它依赖于其编译所在的基础系统,因此可能会出现平台差异 。 Recently¹, a fix has been applied that allows "infinity" as well as "inf" , but that's of minor importance here.
最近¹,已应用了允许“无限”和“ inf”的修复程序,但这在这里意义不大。
The following sections equally well apply to any language that implements IEEE floating point arithmetic correctly, it is not specific to just Python. 以下各节同样适用于可以正确实现IEEE浮点算术的任何语言,不仅限于Python。
When dealing with infinity and greater-than >
or less-than <
operators, the following counts: 当处理无穷大且大于
>
或小于<
运算符时,以下计数:
+inf
is higher than -inf
+inf
任何数字都高于-inf
-inf
is lower than +inf
-inf
在内的任何数字都小于+inf
+inf
is neither higher nor lower than +inf
+inf
既不高于也不低于 +inf
-inf
is neither higher nor lower than -inf
-inf
既不高于也不低于-inf
NaN
is false ( inf
is neither higher, nor lower than NaN
) NaN
比较都是错误的( inf
既不高于也不低于NaN
) When compared for equality, +inf
and +inf
are equal, as are -inf
and -inf
. 比较相等时,
+inf
和+inf
相等, -inf
和-inf
也相等。 This is a much debated issue and may sound controversial to you, but it's in the IEEE standard and Python behaves just like that. 这是一个争议很大的问题,可能对您有争议,但这是IEEE标准中的内容,Python的行为与此类似。
Of course, +inf
is unequal to -inf
and everything, including NaN
itself, is unequal to NaN
. 当然,
+inf
不等于-inf
并且包括NaN
本身在内的所有东西都不等于NaN
。
Most calculations with infinity will yield infinity, unless both operands are infinity, when the operation division or modulo, or with multiplication with zero, there are some special rules to keep in mind: 除非两个操作数都为无穷大,否则大多数无穷大计算都会产生无穷大,当运算除法或取模或与零相乘时,要牢记一些特殊规则:
NaN
NaN
0.0
or -0.0
². 0.0
或-0.0
。 NaN
. NaN
。 inf - inf
, the result is undefined: NaN
; inf - inf
,结果不确定: NaN
; inf - -inf
, the result is inf
; inf - -inf
时,结果是inf
; -inf - inf
, the result is -inf
; -inf - inf
时,结果是-inf
; -inf - -inf
, the result is undefined: NaN
. -inf - -inf
,结果是不确定的: NaN
。 inf + inf
, the result is inf
; inf + inf
,结果是inf
; inf + -inf
, the result is undefined: NaN
; inf + -inf
,结果是不确定的: NaN
; -inf + inf
, the result is undefined: NaN
; -inf + inf
,结果是不确定的: NaN
; -inf + -inf
, the result is -inf
. -inf + -inf
,结果是-inf
。 math.pow
, pow
or **
is tricky, as it doesn't behave as it should. math.pow
, pow
或**
很棘手,因为它的行为不正常。 It throws an overflow exception when the result with two real numbers is too high to fit a double precision float (it should return infinity), but when the input is inf
or -inf
, it behaves correctly and returns either inf
or 0.0
. inf
或-inf
,它的行为正确并返回inf
或0.0
。 When the second argument is NaN
, it returns NaN
, unless the first argument is 1.0
. NaN
,除非第一个参数为1.0
,否则它将返回NaN
。 There are more issues, not all covered in the docs . math.exp
suffers the same issues as math.pow
. math.exp
遭受同样的问题math.pow
。 A solution to fix this for overflow is to use code similar to this: 解决此溢出问题的解决方案是使用类似于以下代码:
try: res = math.exp(420000) except OverflowError: res = float('inf')
Note 1: as an additional caveat, that as defined by the IEEE standard, if your calculation result under-or overflows, the result will not be an under- or overflow error, but positive or negative infinity: 1e308 * 10.0
yields inf
. 注1:作为附加的警告,如IEEE标准所定义,如果您的计算结果不足或
1e308 * 10.0
,结果将不是不足或1e308 * 10.0
误差,而是正负无穷大: 1e308 * 10.0
产生inf
。
Note 2: because any calculation with NaN
returns NaN
and any comparison to NaN
, including NaN
itself is false
, you should use the math.isnan
function to determine if a number is indeed NaN
. 注2:由于任何计算
NaN
返回NaN
任何比较NaN
,包括NaN
本身是false
,你应该使用math.isnan
函数来确定数字确实是NaN
。
Note 3: though Python supports writing float('-NaN')
, the sign is ignored, because there exists no sign on NaN
internally. 注意3:尽管Python支持编写
float('-NaN')
,但该符号会被忽略,因为在NaN
内部不存在任何符号。 If you divide -inf / +inf
, the result is NaN
, not -NaN
(there is no such thing). 如果将
-inf / +inf
除以,则结果为NaN
,而不是-NaN
(没有这样的东西)。
Note 4: be careful to rely on any of the above, as Python relies on the C or Java library it was compiled for and not all underlying systems implement all this behavior correctly. 注意4:请谨慎使用上述任何内容,因为Python依赖于为其编译的C或Java库,并且并非所有底层系统都能正确实现所有这些行为。 If you want to be sure, test for infinity prior to doing your calculations.
如果要确定,请在进行计算之前测试无穷大。
¹) Recently means since version 3.2 . ¹)最近是指从3.2版开始 。
²) Floating points support positive and negative zero, so: x / float('inf')
keeps its sign and -1 / float('inf')
yields -0.0
, 1 / float(-inf)
yields -0.0
, 1 / float('inf')
yields 0.0
and -1/ float(-inf)
yields 0.0
. ²)浮动点支持正和负零,因此:
x / float('inf')
保持其符号和-1 / float('inf')
产生-0.0
, 1 / float(-inf)
产生-0.0
, 1 / float('inf')
产生0.0
和-1/ float(-inf)
产生0.0
。 In addition, 0.0 == -0.0
is true
, you have to manually check the sign if you don't want it to be true. 此外,
0.0 == -0.0
为true
,如果您不希望它为true
,则必须手动检查该符号。
You can still get not-a-number (NaN) values from simple arithmetic involving inf
: 您仍然可以通过涉及
inf
简单算法获得非数字(NaN)值:
>>> 0 * float("inf")
nan
Note that you will normally not get an inf
value through usual arithmetic calculations: 请注意,通常不会通过常规的算术计算获得
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')
The inf
value is considered a very special value with unusual semantics, so it's better to know about an OverflowError
straight away through an exception, rather than having an inf
value silently injected into your calculations. inf
值被认为是具有特殊语义的非常特殊的值,因此最好立即通过异常了解OverflowError
,而不是将inf
值静默注入计算中。
The IEEE 754 floating point representation used by all modern processors has several special bit patterns reserved for positive infinity (sign=0, exp=~0, frac=0), negative infinity (sign=1, exp=~0, frac=0), and many NaN (Not a Number: exp=~0, frac≠0). 所有现代处理器使用的IEEE 754浮点表示法具有几个特殊的位模式,分别保留用于正无穷大(符号= 0,exp =〜0,frac = 0),负无穷大(符号= 1,exp =〜0,frac = 0) )和许多NaN(非数字:exp =〜0,frac≠0)。
All you need to worry about: some arithmetic may cause floating point exceptions/traps, but those aren't limited to only these "interesting" constants. 您只需要担心的事情:某些算术运算可能会导致浮点异常/陷阱,但不仅限于这些“有趣的”常量。
I found a caveat that no one so far has mentioned. 我发现到目前为止,没有人提到过一个警告。 I don't know if it will come up often in practical situations, but here it is for the sake of completeness.
我不知道在实际情况下是否经常出现这种情况,但这是出于完整性考虑。
Usually, calculating a number modulo infinity returns itself as a float, but a fraction modulo infinity returns nan
(not a number). 通常,计算模无穷大会以浮点数形式返回自己,但是分数模无穷小会返回
nan
(不是数字)。 Here is an example: 这是一个例子:
>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan
I filed an issue on the Python bug tracker. 我在Python Bug Tracker上提出了一个问题。 It can be seen at https://bugs.python.org/issue32968 .
可以在https://bugs.python.org/issue32968上看到。
Update: this will be fixed in Python 3.8 . 更新:这将在Python 3.8中修复 。
A VERY BAD CAVEAT : Division by Zero
非常糟糕的警告:被零除
in a 1/x
fraction, up to x = 1e-323
it is inf
but when x = 1e-324
or little it throws ZeroDivisionError
以
1/x
分数表示,直到x = 1e-323
为止都是inf
但是当x = 1e-324
或ZeroDivisionError
它抛出ZeroDivisionError
>>> 1/1e-323
inf
>>> 1/1e-324
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero
so be cautious! 所以要小心!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.