C ++中除法和乘法特殊排序的原因

时间:2009-12-03 15:14:12

标签: c++ double math

我正在将一些c ++代码移植到java中,并且我一直在运行实例,其中任何编写它的人都会继续执行以下操作:

double c = (1.0/(a+1.0)*pow(b, a+1.0));
double d = (1./(integral(gamma, dmax)-integral(gamma, dmin)))*(integral(gamma+1, dmax)-integral(gamma+1, dmin));

而不是:

double c = pow(b, a+1.0)/(a+1.0);
double d = (integral(gamma+1, dmax)-integral(gamma+1, dmin))/(integral(gamma, dmax)-integral(gamma, dmin));

第二个似乎更清楚,除非我对C ++中的操作顺序错了,否则他们应该做同样的事情。有没有理由做第一个而不是第二个?我唯一能想到的就是精确的一些奇怪的情况。

3 个答案:

答案 0 :(得分:6)

是的,他们是一样的。我能想到的唯一原因是数学清晰度:有时当你对数量进行标准化时,你经常会写:

answer = (1/total) * (some of it)

例如,柯西的积分定理经常被写成

f(a) = (1/(2*pi*i)) * integral(f(z)/(z-a), dz)

答案 1 :(得分:2)

如果a保持不变且b正在发生变化(例如,如果您的代码处于循环中并且很明显a在两次迭代之间没有变化,例如因为它是一个const变量),那么原始版本可以更快地执行,因为乘法比除法更便宜(假设编译器将1/...的计算移出循环)。

如果这是理由,这似乎是误导性的优化尝试,但并不意味着它不是它。

哦,就精确度而言,原始版本实际上稍微不如你的精确,如果有的话,因为1/...还有一个额外的舍入误差。正是这种舍入错误阻止了编译器将你的版本转换为自己意志的原始版本:它们不会计算完全相同的东西(但是非常接近的东西)。

答案 2 :(得分:1)

是的他们应该做同样的事情。原作者可能一直在复制其他地方的方程式