Reputation: 1540
I have a simple recursive function that calculates a simple pendulum swing decay, using the ratio of height1:height2 of 0.98.
The function has a base case of 0.0, but for some reason it turns into infinite self-calls!
Can anyone spot what I'm missing?
Code:
float swingDecay (float value) {
if ( value == 0.00 ) {
return value;
}
else {
return swingDecay (value * 0.98); }
}
mIL3S www.milkdrinkingcow.com
Upvotes: 1
Views: 165
Reputation: 215221
You could check if (value * 0.98 == value)
instead of if (value == 0)
. This condition will be met exactly when value
becomes so small (subnormal) that it has too few bits of precision for multiplication by 0.98
to yield a different result.
Upvotes: 1
Reputation: 1540
Wow, thanks for the quick answer everyone!
Apparently that little floating point detail was skipped in my class... So since everyone is pretty much saying the same thing (don't compare floating points with equality since they're never really exact), does the same hold true if I used ints or doubles?
Originally I had the test as if ( value <= 0.0 ), but that gave me the same thing.
Just ran it with the test as <= 0.005 and that seemed to be just fine!
Thanks all!
mIL3S
www.milkdrinkingcow.com
Upvotes: 0
Reputation: 68006
You should always use 'approximate' comparisons in floating point calculations. E.g., if (abs(value) < EPS)
instead of if ( value == 0.00 )
. EPS
here is a small constant (depends on your requirements and datatype).
I suspect this is what's actually happening. You get to the smallest possible positive value in your datatype, like 1 * 2^(-10000)
(10000 comes from the top of my head) and now value * 0.98 = value
. E.g., it has to be rounded either to 0
or to total
and 0.98*total
is obviously closer to total
.
But that's only speculations, though. With floating point computations, you can never be sure :)
Upvotes: 6
Reputation: 9436
don't compare float values with constants, always check if they fall under a lower-bound. change your value == 0.00 to value <= 0.0001 for example
Upvotes: 0
Reputation: 2454
( value == 0.00 )
Never gets true. Or, it takes so many runs of the function that the it runs into, well, stack overflow :P You should take another look at how you made your function. Right now it is not even useful, it can only ever return 0.
Upvotes: 2
Reputation: 18068
use this (as seems you are going for 2 digit accuracy.
if (value < 0.001 )
You should not use equality for floating point values.
Upvotes: 0
Reputation: 3180
Do not directly compare floating point numbers; your "value" will probably never really be 0.0 (zero).
do something like :
float smallNumber = 0.00001;
if ( value < smallNumber )
{
...
}
Upvotes: 2
Reputation: 24375
Due to floating point calculations never being exact in floating point math you never get to value == 0.00. You might want to try something like value < 0.0000001 or something like that and tweak it where it works.
Upvotes: 4