Python decimal.decimal精度不';t匹配wolfram alpha';s

Python decimal.decimal精度不';t匹配wolfram alpha';s,python,wolfram-mathematica,decimal,wolframalpha,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.9900399200799679944040576629049610346557098388671875 根据这一点,Wolfram alpha在这里实际上是错误的 (1

我有以下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.9900399200799679944040576629049610346557098388671875

根据这一点,Wolfram alpha在这里实际上是错误的

(1 - 0.002) ** 5
正是
0.990039920079968

您可以通过简单评估
后面是否有15位数字来验证,这与
5*3
匹配,3是表达式
(1-0.002)
后面的数字。根据定义,第15位之后不能有任何数字

编辑 再深入一点,我发现了一些有趣的东西:

此符号
Decimal('0.002')
使用此精确值创建实际十进制。使用
Decimal(0.002)
小数由浮点而不是字符串组成,从而产生不精确性。使用此符号是原始公式:

(1-decimal.Decimal(0.002))**5
返回
十进制('0.9900399200799679997934935280741175489710165953457375376490552859002826694496107'
,它确实是
后面的80位数字,但与wolfram alpha值不同

这可能是由于python和wolfram alpha浮点表示之间的精度差异造成的,这进一步表明在使用SetPrecision时wolfram alpha正在使用浮点


Nota:直接请求结果会返回正确的值(请参阅)如果wolfram错了,尝试一下1的幂,你会得到
0.9999999999999998223643160599749535322183310546875
而不是
0.998
。他们可能使用浮点数。

这里发生了什么:因为它看起来像是Mathematica编程语言的语法,WolframAlpha正在解释t他输入
SetPrecision[(1-0.002)^5,80]
作为Mathematica源代码,继续计算。在Mathematica中,正如其他人在其他答案中猜测的那样,0.002是机器精度浮点文字值。舍入错误随之发生。最后,SetPrecision将生成的机器精度值转换为最接近的80精度值

要解决这个问题,你有两个选择

  • 你可以试着让WolframAlpha不认为你是在输入Mathematica编程语言的代码,这样它就有了自己的魔力
  • 在要求WolframAlpha计算的Mathematica代码中,可以输入无限精度文字,而不是机器精度文字0.002。有几种方法,但这里有一种:
  • 最后,我想指出,在Mathematica中,通过扩展由Mathematica代码组成的WolframAlpha查询,您通常需要N(),而不是。它们通常相似(在本例中相同),但有一个细微的区别:

    • SetPrecision[…,n]首先将所有包含的数字设置为精度n,然后计算所有值(随后将出现舍入错误)
    • N[…,N]基本上反复尝试以越来越高的精度设置精度,直到最终舍入误差几乎肯定小于N
    N的工作稍难一些,但可以得到正确数字的正确数目(假设输入足够精确)


    因此,我最后建议使用WolframAlpha通过Mathematica代码进行计算。

    在Andrews回答之后,输入文字的精度在SetPrecision指令到达之前被视为机器精度

    另一个解决方案是,它保留了您的基本输入符号,这是很好的,它使用backtic符号直接指定文本的精度:

    SetPrecision[(1-.002`80)^5, 80]
    
    产生期望的结果

    对于仍然不跟随的任何人,您也可以输入所有的零

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

    alpha和mathematica中的这些工作..

    fwiw wolframalpha如果不以设定精度包装表达式,则会得到精确的结果..谢谢您的评论。我在尝试计算此表达式时遇到另一个问题:100*(1-0.002)^5*(1-0.005)*(1-0.006)*3.5.Mathematica出于某种原因将数字四舍五入到342.7127137548418,而网站输出的是正确答案*%281+-+0.002%29%5E5*%281+-+0.005%29*%281+-+0.006%29*3.5我想这与您在这里陈述的原因相同,但有办法解决吗?解决方法是一样的:替换4个机器精度浮点字面值使用精确或高精度文字。对于高精度,请使用例如3.5`80。对于精确,请使用35/10或SetPrecision[3.5,无穷大)。使用哪种文字(高精度或精确),当然取决于您对该值的了解程度!