Python decimal.Decimal precision与wolfram alpha不匹配

时间:2013-11-08 16:32:07

标签: python wolfram-mathematica decimal wolframalpha

我有以下python代码:

In [1]: import decimal

In [2]: decimal.getcontext().prec = 80

In [3]: (1-decimal.Decimal('0.002'))**5
Out[3]: Decimal('0.990039920079968')

不应与0.99003992007996799440405766290496103465557098388671875匹配 根据这个http://www.wolframalpha.com/input/?i=SetPrecision%5B%281+-+0.002%29%5E5%2C+80%5D

4 个答案:

答案 0 :(得分:3)

Wolfram alpha在这里实际上是错误的。

(1 - 0.002) ** 5

正好是0.990039920079968

您可以通过简单地评估.之后的15个数字(匹配5 * 3来验证,3是表达式{{1}中.之后的数字位数}}。根据定义,在15日之后不能有任何数字。

修改

多挖一点让我感到有趣:

此表示法(1 - 0.002)使用此完全值创建实际小数。使用Decimal('0.002')十进制是从浮点而不是字符串,创建一个不精确。使用这种表示法是原始公式:

Decimal(0.002)

返回(1-decimal.Decimal(0.002))**5 ,它在Decimal('0.99003992007996799979349352807411754897106595345737537649055432859002826694496107'之后确实长了80位,但与wolfram alpha值不同。

这可能是由python和wolfram alpha浮点表示之间的精度差异引起的,并且进一步表明当使用SetPrecision时,wolfram alpha正在使用浮点数。

Nota :直接询问结果会返回正确的值(请参阅http://www.wolframalpha.com/input/?i=%281+-+0.002%29%5E5)。

答案 1 :(得分:3)

以下是这里发生的事情:因为它看起来像Mathematica编程语言的语法,WolframAlpha将输入SetPrecision[(1 - 0.002)^5, 80]解释为Mathematica源代码,然后进行评估。在Mathematica中,正如其他人在其他答案中推测的那样,0.002是机器精度浮点字面值。发生了临时错误。最后,由SetPrecision将得到的机器精度值投射到最接近的80精度值。

要解决这个问题,您有几种选择。

  1. 你可以尝试让WolframAlpha不要以为你是从Mathematica编程语言输入代码,这样它就会有自己的魔力。正如njzk2所述,输入(1 - 0.002)^5即可。
  2. 在您要求WolframAlpha评估的Mathematica代码中,您可以输入无限精度文字而不是机器精度文字0.002。有几种方法,但这里有一种方法:SetPrecision[(1 - 2*^-3)^5, 80]
  3. 最后,我想指出在Mathematica中,以及在由Mathematica代码组成的WolframAlpha查询中的扩展,通常需要N(documentation)而不是SetPrecision。它们通常相似(在这种情况下相同),但有一个微妙的区别:

    • SetPrecision [...,n]首先将所有包含的数字设置为精度n,然后评估所有内容(随后将出现舍入错误)
    • N [...,n]基本上以更高和更高的精度重复尝试SetPrecision,直到最终的舍入误差几乎肯定小于n。

    N的工作稍微努力,但能获得正确数字的正确数字(假设输入足够精确)。

    所以我使用WolframAlpha通过Mathematica代码进行计算的最终建议是N[(1 - 2*^-3)^5, 80]

答案 2 :(得分:2)

wolfram是错误的,尝试使用它的力量而你得到0.9979999999999999982236431605997495353221893310546875而不是0.998。他们可能使用浮点数。

答案 3 :(得分:2)

按照安德鲁斯的回答,这是在SetPrecision指令到达之前输入的文字精度被视为机器精度的结果。

对此的另一个解决方案,即它保留基本输入表示法很好,就是用带有符号的符号直接指定文字的精度:

SetPrecision[(1-.002`80)^5, 80]

产生预期的结果。

对于仍然没有关注的人,你也可以键入所有的零..

 SetPrecision[(1-.0020000000000000000000000...0000)^5, 80]

这些工作在alpha和mathematica ..