如何在Python中使用精确的浮点算法?

如何在Python中使用精确的浮点算法?,python,math,floating-point,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之前,每个单独部分的结

我在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之前,每个单独部分的结果是完全相同的。 因此((x-m)110.0(1-m))**b和((x-m)110.0(1-m))**c与excel计算值完全相同,但当它们乘以较大的数字时,它们会完全改变

我该怎么做?我必须使用不同的语言吗?这个问题只在python中存在,还是在所有语言中都存在


编辑:excel中的公式与python中的公式完全相同。完全一样。在我乘以a和-a之前,数字也是一样的。然后他们两个都差5分左右。excel中x=0.5和m=0.265的答案约为0.47,而python的答案约为-0.67

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


根据定义,浮点运算并非完全100%准确,因为值是用分数表示的。请看一看这篇文章,以及另一篇文章。

很难理解您所寻求的精度,但我认为您也可以看看-

它提供了几个优于传统方法的优点 浮点数据类型:

“十进制”是基于浮点的 与人一起设计的模型 在心里,必然有一个 首要指导原则- 计算机必须提供一种算法 这与 人们学习的算术 学校。”——摘自小数点 算术规范

可以表示十进制数 确切地相比之下,数字像1.1 和2.2没有精确的 二进制浮点表示法 指向最终用户通常不会这样做 期望1.1+2.2显示为 3.30000000000000003,与二进制浮点相同

这种精确性一直延续到 算术。在十进制浮点中, 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


我使用以下值进行了尝试(我为
a
选择了十万中的某个值,因为这与您的描述一样具体):

计算内部值:

>>> 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中的不同之处,您需要准确地告诉我们您是如何在Excel中进行计算的。这意味着要将公式放入单元格以生成值。告诉我们它们是完全一样的是没有用的,因为这不会给我们任何继续下去的机会。从这里开始,我的猜测是它们事实上并不相同,因为我认为浮点错误或类似错误不太可能是导致问题中报告的错误大小的原因。很可能您在某个地方有输入错误或误解。

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

真的,如果你不在乎视觉效果,只要在整个过程中保持数字的一小部分,你的问题就解决了。如果你真的想看到小数点,你需要意识到,在这种情况下,任意精度将是一个相当复杂的过程,因为你必须处理重复的值(就像第三个值永远是三个,在
0.
之后)。尽管如此,还是有人试图解决这个问题。让它精确到某个小数点应该是可能的,但是如果你不使用分数,不要期望超过这个小数点

分数有分子和分母(我认为它们存储为long,Python中的long已经具有任意精度;因此,分子和分母的数字可以任意大)。我编写了一些代码,用于将分数从
1234/12
样式转换为
23/4
样式。但是,我不想通过在这里发布它来给它CC许可证(我更喜欢真正的软件许可证,比如MIT)。所以,如果你有兴趣,你必须让我知道

下面是如何使用分数的示例。分数:

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
不管怎样,你可以像对待其他数字一样对待它们。你可以像yo一样将事物转换成分数
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