首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >浮点除法与乘法的精度差异

浮点除法与乘法的精度差异
EN

Stack Overflow用户
提问于 2011-06-26 15:18:30
回答 3查看 1.7K关注 0票数 9

这有什么区别吗:

代码语言:javascript
复制
average = (x1+x2)/2;
deviation1 = x1 -average;
deviation2 = x2 -average;
variance = deviation1*deviation1 + deviation2*deviation2;

还有这个:

代码语言:javascript
复制
average2 = (x1+x2);
deviation1 = 2*x1 -average2;
deviation2 = 2*x2 -average2;
variance = (deviation1*deviation1 + deviation2*deviation2) / 4;

请注意,在第二个版本中,我试图尽可能延迟除法。通常情况下,第二个版本的延迟划分会提高准确性吗?

上面的代码片段只是一个例子,我并不打算优化这个特定的代码片段。

顺便说一句,我问的是一般的除法,而不仅仅是2或2的幂,因为它们简化为IEEE 754表示中的简单移位。我取除以2,只是为了用一个非常简单的例子来说明这个问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-26 15:27:43

这不会带来任何好处。你只是改变了比例,但在你的计算中不会得到更多有意义的数字。

Wikipedia article on variance在高层次上以健壮的方式解释了计算方差的一些选项。

票数 4
EN

Stack Overflow用户

发布于 2011-06-26 15:44:03

我不得不同意大卫·赫弗南的观点,它不会给你更高的精确度。

原因在于浮点值的存储方式。有些位表示有效数字,有些位表示指数(例如3.1714x10-12)。无论你的数字有多大,有效数字的位数总是相同的--这意味着最终的结果不会真的不同。

更糟糕的是-如果你有非常大的数字,延迟除法可能会导致溢出。

如果你真的需要更高的精度,有很多库允许更大的数字或更高精度的数字。

票数 1
EN

Stack Overflow用户

发布于 2011-06-26 16:01:03

回答问题的最好方法是运行测试(包括随机分布的测试和基于范围的测试?)并查看所得到的数字在二进制表示中是否完全不同。

请注意,如果这样做,您将遇到的一个问题是,由于编码平均的方式,您的函数将不适用于值> MAX_INT/2

代码语言:javascript
复制
avg = (x1+x2)/2        # clobbers numbers > MAX_INT/2
avg = 0.5*x1 + 0.5*x2  # no clobbering

不过,这几乎肯定不是问题,除非您正在编写语言级别的库。如果你的大多数数字都很小,那可能根本无关紧要?事实上,它可能不值得考虑,因为方差的值将超过MAX_INT,因为它本质上是一个平方量;我想说你可能希望使用标准差,但没有人这样做。

在这里,我用python做了一些实验(我认为python支持IEEE,因为它可能将数学委托给C库……):

代码语言:javascript
复制
>>> def compare(numer, denom):
...     assert ((numer/denom)*2).hex()==((2*numer)/denom).hex()

>>> [compare(a,b) for a,b in product(range(1,100),range(1,100))]

没问题,我想,因为除以2和乘以2可以很好地用二进制表示。但是,请尝试乘除3:

代码语言:javascript
复制
>>> def compare(numer, denom):
...     assert ((numer/denom)*3).hex()==((3*numer)/denom).hex(), '...'

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
  File "<stdin>", line 2, in compare
AssertionError: 0x1.3333333333334p-1!=0x1.3333333333333p-1

这可能很重要吗?也许如果您正在处理非常小的数字(在这种情况下,您可能希望使用log算法)。但是,如果您正在处理大数字(概率上不常见),并且延迟除法,您将会像我前面提到的那样发生风险溢出,但更糟糕的是,由于难以阅读的代码,可能会出现风险错误。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6482660

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档