我一直在試驗標準的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