2011-07-03 88 views
-3

我在使用浮点运算的python中遇到了这个问题。 我解方程去如下:如何在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。 (1-m))** b和((xm)110.0(1-m))** c与其excel计算值完全相同,但当它们相乘由大量他们完全改变。

我如何做到这一点?我必须使用不同的语言吗?这个问题只是在python中,还是在所有语言?

编辑:这是在Excel中完全相同的公式在Python中。一模一样。直到我乘以a和-a,数字也是相同的。那么他们都得到5分的东西。在Excel中的答案是对于x = 0.5且m = 0.265左右0.47而对于蟒答案是围绕-0.67

+3

-1:你会得到什么结果,你期望得到什么结果?你尝试过简化等式吗?你尝试过比较中间结果吗? –

+1

“完全不准确”?你能证明你有什么吗? –

+0

回应以上。向我们展示你在excel中使用的等式,在excel中的结果以及在python中的结果。 –

回答

4

mpmath可以是答案

Mpmath为 多倍浮动纯Python库算术。它提供了一个丰富 组的超越函数, 无限指数大小,复杂 号码,区间算术, 数值积分和 分化,求根,线性代数 ,等等。

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

+0

刚刚尝试mpf(),它仍然没有工作...给出相同的价值,如果我将dps更改为更大的数字,它变得不太准确,而不是更准确 – sbeleidy

+0

我认为你的问题在别处,sbeleidy。做我们所问:在excel中显示你的方程,在Python中显示你的方程,以及一些不符合的典型结果。 –

4

这是挺难理解你所寻找的东西精确度,但我认为你还可以看看decimal module. -

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

十进制“是基于一个浮点 模型这是设计时考虑到人 ,而且必然有一个最重要的 指导原则 - 电脑必须提供一个算术 是WOR ks以与 算术相同的方式学习,在 学校学习。“ - 摘自小数点 算术规范。

准确地说,十进制数可以表示为 。相比之下,像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。

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中不同,你需要告诉我们究竟如何你正在Excel中进行计算。这意味着您要放入单元格中以生成值的公式。告诉我们他们完全一样没有用,因为它不会给我们任何东西继续。从这里,我的猜测是,他们实际上并不相同,因为我认为这不太可能浮点误差等原因将是一个错误的原因,你在你的问题的报告的大小。这更可能是您在某处存在拼写错误或误解。

+1

'final = aexp1 + aexp2':这里存在固有的精度损失,因为'aexp1'和'aexp2'在数值上几乎相等,但符号相反。多少错误?表达式可以重写为'-2 * a * inner * math.sinh(2e-7 * math.log(inner))',从而避免了精度损失问题。结果是-11.1886708992(与Blair的-11.188670896相比)。假设python在引擎盖下使用IEEE双精度,减法失去6个小数位。 **注意好的**:这不是sbeleidy产生的那种错误。 –

1

如果您只是想要进行任意精度算术,请使用属于标准库的fractions模块中的Fraction类。完成计算后,可以将其转换为浮点数(如果必须的话)。不幸的是,所得到的浮动可能不是任意精度的,但所有的计算,直到转换为浮动会,并因此比如果你使用花车的整个时间你的持股量将有可能更加准确。

真的,如果你不关心视觉效果,只需要把数字保持在一个分数,你的问题就解决了。如果你关心的是看到小数点,那么你需要认识到在这种情况下的任意精度将是一个相当复杂的过程,因为那样你就必须处理重复的值(比如第三个是永远的三分之一) ,在0.之后)。尽管如此,还有人试图解决这个问题。准确地将它精确到一定的小数点肯定是可能的,但不要期望更多,如果你不使用分数。分数有分子和分母(我认为长时间存储,我相信,Python中的long已经是任意的精度;因此,对于分子和分母都可以有大小)。我写了一些代码,用于将1234/12风格的分数转换为2 3/4风格。但是,我不想通过在这里发布CC许可证(我宁愿一个真正的软件许可证,如MIT)来给它颁发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)会将浮点数转换为分数)。你也可以围绕他们,或者其他任何东西。

我发现分数类大大低于代表。我用了很多。这很棒。

+0

注意:将第一个参数转换为字符串对于防止浮点舍入错误是非常必要的:'float(Fraction(5.6) - 5)'仍然是'.5999 ...',但是float(Fraction(“5.6” ) - 5)'是'0.6' –