1

我有一个简单的递归函数,它使用 0.98 的高度 1:高度 2 的比率计算简单的钟摆摆动衰减。

该函数的基本情况为 0.0,但由于某种原因,它变成了无限的自调用!

谁能发现我错过了什么?

代码:

float swingDecay (float value) {


     if ( value == 0.00 ) {
          return value;
     }

     else { 
          return swingDecay (value * 0.98);  }     
}

mIL3S www.milkdrinkingcow.com

4

8 回答 8

6

您应该始终在浮点计算中使用“近似”比较。例如,if (abs(value) < EPS)代替if ( value == 0.00 ). EPS这是一个小常数(取决于您的要求和数据类型)。

我怀疑这是实际发生的事情。您可以在数据类型中获得最小的正值,例如1 * 2^(-10000)(10000 来自我的头顶) 和 now value * 0.98 = value。例如,它必须舍入到0total并且0.98*total显然更接近total
但这只是猜测。使用浮点计算,您永远无法确定:)

于 2011-01-07T18:32:22.447 回答
4

由于浮点计算在浮点数学中永远不会精确,因此您永远不会得到值 == 0.00。您可能想尝试像 value < 0.0000001 或类似的东西,并在它工作的地方调整它。

于 2011-01-07T18:32:27.140 回答
2

不要直接比较浮点数;您的“价值”可能永远不会真正为 0.0(零)。

做类似的事情:

float smallNumber = 0.00001;
if ( value < smallNumber )
{
...
}
于 2011-01-07T18:32:51.100 回答
2

(值 == 0.00)

永远不会成真。或者,它需要运行如此多的函数,以至于它运行到,好吧,堆栈溢出:P 你应该再看看你是如何制作你的函数的。现在它甚至没有用,它只能返回 0。

于 2011-01-07T18:33:58.620 回答
1

您可以检查if (value * 0.98 == value)而不是if (value == 0). value当它变得如此之小(次正规)以至于它的精度太少而无法乘以0.98产生不同的结果时,就会恰好满足此条件。

于 2011-01-07T19:05:04.027 回答
0

使用它(好像您要获得 2 位精度。

if (value < 0.001 )

您不应该对浮点值使用相等性。

于 2011-01-07T18:33:48.247 回答
0

不要将浮点值与常量进行比较,始终检查它们是否低于下限。例如,将您的值 == 0.00 更改为值 <= 0.0001

于 2011-01-07T18:35:28.337 回答
0

哇,谢谢大家的快速回答!

显然,我的课上跳过了一点浮点细节......所以因为每个人都在说同样的事情(不要将浮点数与相等性进行比较,因为它们从来都不是真正精确的),如果我使用过同样适用整数还是双精度数?

最初我的测试好像是( value <= 0.0 ),但这给了我同样的东西。

只需将其测试为 <= 0.005 就可以了,这似乎很好!

谢谢大家!

mIL3S

www.milkdrinkingcow.com

于 2011-01-07T18:52:49.407 回答