重新调整浮点方程

时间:2009-05-27 18:51:25

标签: floating-point precision linear-algebra

我想知道是否有办法提高计算斜率的准确性。 (几个月后出现here)。

似乎改变了:

float get_slope(float dXa, float dXb, float dYa, float dYb) {
    return (dXa - dXb)/(dYa - dYb);
}

float get_slope(float dXa, float dXb, float dYa, float dYb) {
    return  dXa/(dYa - dYb) - dXb/(dYa - dYb);
}

可能是一种改进。建议?

编辑:我追求的是精确度,而不是效率。

3 个答案:

答案 0 :(得分:5)

将它们转换为函数内的 double


当你遇到麻烦的时候,分母接近于零,显然。你的坡度将接近无穷大。所以很大程度上取决于你想要用斜坡做什么。有时,如果您知道delta y将接近零,则可以计算斜率的倒数并使用它。您甚至可以检测哪个更小 - deltax或deltay的绝对值并返回斜率或1 /斜率。另请参阅atan2()。


如果您知道输入是十进制的,并且您希望输出也是十进制的,那么您可以通过使用十进制库进行所有计算来克服将浮点数转换为二进制和返回所固有的精度损失。我记得当我使用Atari BASIC进行十进制计算时我很高兴,因为它使用了6502的BCD模式。

答案 1 :(得分:1)

我认为你有一个错字。你可能意味着

return  dXa/(dYa - dYb) - dXb/(dYa - dYb);

我想说你给出的第一种形式具有更高的精确度。如果dXa和dXb接近且很大,那么在减去之前你将失去两个分区的精度。

答案 2 :(得分:1)

如果你不介意燃烧一些额外的周期,你可以通过循环来获得更好的准确性。

计算A和B之间的线段的斜率。

计算{(Xa - (Xa -Xb)),(Ya - (Ya -Yb)}和{(Xb +(Xa - Xb))之间的线段的斜率,(Yb +(Ya - Yb) )} ...基本上是A - 斜率和B +斜率。

然后比较得到的斜率。如果差异太大(选择你想要的门槛),那么继续前进,并在最后平均所有斜率。

这可以帮助消除由非常小的斜率浮点运算引起的异常。