我一直在试验标准的Python数学模块,并遇到了一些微妙的困难。例如,我注意到有关不定形以下行为:Python数学模块微妙
0**0
>>> 1
def inf():
return 1e900
# Will return inf
inf()**inf()
>>> inf
和其它种类的异常。我正在写一个计算器,我希望它在数学上是准确的。我能做些什么吗?或者,有什么办法可以绕过这个?提前致谢。
我一直在试验标准的Python数学模块,并遇到了一些微妙的困难。例如,我注意到有关不定形以下行为:Python数学模块微妙
0**0
>>> 1
def inf():
return 1e900
# Will return inf
inf()**inf()
>>> inf
和其它种类的异常。我正在写一个计算器,我希望它在数学上是准确的。我能做些什么吗?或者,有什么办法可以绕过这个?提前致谢。
你的第一个例子没有问题。 0**0
通常被定义为1.第二个例子是所有与双精度有关的事情。 1E900
超过(最有可能的64位)双倍的最大正值。如果你想在这个范围之外加倍,你必须看看图书馆。幸运的是Python有一个内置的:the decimal module。
例如:
from decimal import Decimal
d = Decimal('1E900')
f = d + d
print(f)
>>> 2E900
谢谢!我不知道十进制模块,应该派上用场。 – ThisIsNotAnId 2012-02-08 00:51:52
根据钨(引用Knuth的),而0 ** 0是不确定的,它有时给定为1,这是因为保持该语句的 'x ** 0 = 1' 到在所有情况下都是如此,在某些情况下是有用的。更有趣的是,Python将NaN ** 0视为1。
http://mathworld.wolfram.com/Power.html
在无穷**无穷大,你没有真正处理无穷的数学概念在这里(其中那将是不确定的)的情况下,而是一个数字太大了,而且已经溢出。因此,这句话所说的是,对于另一个庞大的数字来说,巨大的数字仍然是一个巨大的数字。
编辑:我不认为有可能在Python中重载内置类型(例如float),以便直接重载float .__ pow __(x,y)运算符。你可能做的是定义你自己的float版本。
class myfloat(float):
def __pow__(x,y):
if(x==y==0):
return 'NaN'
else:
return float.__pow__(x,y)
m = myfloat(0)
m**0
不确定这是不是你正在寻找的。
谢谢MDT。有没有办法解决?例如,对于我的计算器,我能否以某种方式告诉解释器是否遇到'0 ** 0'输入(不一定是字符串),返回''Indeterminate form.''? – ThisIsNotAnId 2012-02-07 05:46:55
如果我们假设0**0 == 1
,那么返回NaN的0**0
几乎总是毫无用处,许多算法避免了特殊情况。所以虽然它可能不是数学上的完美 - 我们在这里谈论IEEE-754,但数学正确性实际上是我们问题中最少的[1]
但是如果你想改变它,那很简单。下面将按预期在Python 3.2:
def my_pow(x, y):
if y == 0: return 'NaN'
return float.__pow__(float(x), y)
pow = my_pow
[1]下面的代码在理论上可以执行如果与x86处理器(以及至少在C和共)分支:
float x = sqrt(y);
if (x != sqrt(y)) printf("Surprise, surprise!\n");
您需要知道浮点数是如何工作的:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – duffymo 2012-02-07 03:11:39
从来不知道Python说0^0 == 1>。< – Corbin 2012-02-07 03:12:17
究竟是什么不喜欢这些结果? – sth 2012-02-07 03:15:33