如何在Python中使用准确的浮点运算?

时间:2011-07-03 13:07:08

标签: python math floating-point

我在python中遇到浮点运算这个问题。 我正在解决的等式如下:

-a *((x-m)*110.0*(1-m))**b +a*((x-m)*110.0*(1-m))**c
a is a really large positive number (in the hundred thousands)
b is 1.0000002
c is 0.9999998

当我在excel中执行此操作时,我得到了准确的结果,但是当我在python中执行此操作时,我得到了完全不准确的结果。

每个单独的部分的结果完全相同,直到我乘以-a和a。 所以((xm) 110.0 (1-m))** b和((xm) 110.0 (1-m))** c与它们完全相同excel计算值,但当它们乘以大数时,它们会完全改变。

我该怎么做?我必须使用其他语言吗?这个问题只出现在python中还是用于所有语言?

编辑:它与Excel中的excel完全相同。完全相同的。数字也是相同的,直到我乘以a和-a。然后他们都被5点了。对于x = 0.5和m = 0.265,excel的答案大约为0.47,而python的答案大约为-0.67

5 个答案:

答案 0 :(得分:4)

mpmath可以作为答案

  

Mpmath是一个纯Python库   多精度浮点数   算术。它提供了广泛的   一套超越函数,   无限的指数大小,复杂   数字,区间算术,   数值积分和   分化,寻根,线性   代数等等。

http://code.google.com/p/mpmath/

答案 1 :(得分:4)

很难理解你要寻找的精确度,但我认为你也可以看看decimal module. -

  

它提供了几个优势   float数据类型:

     

十进制“基于浮点数   与人共同设计的模型   记住,必然有一个   最重要的指导原则 -   计算机必须提供算术   它的工作方式与。相同   人们学习的算术   学校。“ - 小数摘录   算术规范。

     

可以表示十进制数字   究竟。相比之下,数字如1.1   和2.2没有确切的   二进制浮动表示   点。最终用户通常不会   期望1.1 + 2.2显示为   3.3000000000000003与二进制浮点一样。

     

准确性延续到了   算术。在十进制浮点数,   0.1 + 0.1 + 0.1 - 0.3正好等于零。在二进制浮点数中   结果是5.5511151231257827e-017。   虽然接近零,但差异很大   阻止可靠的平等测试和   差异可以累积。为了这   原因,小数是首选   会计应用有哪些   严格的平等不变量。

     

十进制模块包含一个   重要地方的概念   1.30 + 1.20是2.50。保留尾随零以表示重要性。这个   是习惯性的陈述   货币申请。对于   乘法,“教科书”   方法使用了所有的数字   被乘数。例如,1.3 * 1.2   给出1.56而1.30 * 1.20给出   1.5600

答案 2 :(得分:2)

浮点运算根据定义并非完全100%准确,因为值表示为分数。请查看有关Python float limitations以及其他more general article

的文章

答案 3 :(得分:1)

我使用以下值尝试了此操作(我为a选择了数十万中的内容,因为这与您的描述具体相符):

>>> a = 500000.0
>>> b = 1.0000002
>>> c = 0.9999998
>>> x = 0.5
>>> m = 0.265

计算内在值:

>>> inner = (x - m) * 110.0 * (1 - m)
>>> print inner
18.99975

和指数:

>>> exponent1 = inner**b
>>> exponent2 = inner**c
>>> print (exponent1, exponent2)
(18.999761188674185, 18.999738811332392)

将指数乘以a

>>> aexp1 = -a * exponent1
>>> aexp2 = a * exponent2
>>> print (aexp1, aexp2)
(-9499880.5943370927, 9499869.4056661967)

最后的答案:

>>> final = aexp1 + aexp2
>>> print final
-11.188670896

您在Excel中获得的这些值是什么?或者,发布您实际使用的a的值,我会更新我的答案。

现在,当人们在评论中问你时,你已经躲过了这个问题,但如果你想让我们弄清楚为什么它在Excel中有所不同,你需要告诉我们< em>完全如何在Excel中进行计算。这意味着您要放入单元格中以生成值的公式。告诉我们它们完全相同没有用,因为它没有给我们任何东西继续下去。从这里开始,我的猜测是它们实际上并不相同,因为我认为浮点错误等不太可能是您在问题中报告的大小错误的原因。你更有可能在某处犯错误或误解。

答案 4 :(得分:1)

如果您只想要任意精度算术,请使用Fraction模块中的fractions类,该模块是标准库的一部分。完成计算后,可以将其转换为浮点数(如果必须)。不幸的是,结果浮点数可能不是任意精度,但是直到转换为浮点数之前的所有计算都是,因此你的浮点数可能比你在整个时间使用浮点数时更准确。

真的,如果你不关心视觉,只需将数字保持整个时间,你的问题就解决了。如果你真的关心看小数点,你需要意识到在这种情况下任意精度将是一个相当复杂的过程,因为那时你必须处理重复值(就像三分之一是一堆三个永远,在0.之后。然而,有人试图解决这个问题。如果你没有使用分数,那么当然可以将其精确到一定的小数点,但如果你没有使用分数,那么不要期望更多。

分数有分子和分母(我相信它们存储为long,而Python中的longs已经是任意精度;因此,对于分子和分母,你可以拥有你想要的数字)。我编写了一些代码,用于将分数从1234/12样式转换为2 3/4样式。但是,我不想通过在此发布它来给它一个CC许可证(我宁愿使用真正的软件许可证,例如麻省理工学院)。所以,如果你有兴趣,你必须告诉我。

以下是如何使用fractions.Fraction的示例:

from fractions import Fraction
x=Fraction("2.234532456345265356356356354624356356235635634563563565635645") #You can add string numbers of any value.
y=Fraction(1, 3234524352345) #This is one 3234524352345th 
x+=5 #adding five (The five doesn't have to be a Fraction object, but the result will be one.)
y=x/y #Dive x by y.
x=float(x) #Converting it into a float

无论如何,你可以像对待任何其他类型的数字一样对待它们。您可以将事物转换为与整数相同的分数(例如Fraction(4.2343)将浮点数转换为分数)。你可以围绕它们,或者其他任何东西。

我发现Fraction类的代表性很低。我经常使用它。太棒了。