Miles Alden
Miles Alden

Reputation: 1540

Simple Recursion Help

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

Answers (8)

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

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

Miles Alden
Miles Alden

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

Nikita Rybak
Nikita Rybak

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

Nylon Smile
Nylon Smile

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

Cray
Cray

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

Sarwar Erfan
Sarwar Erfan

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

Max
Max

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

Romain Hippeau
Romain Hippeau

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

Related Questions