0

I'm having an issue with fmod() where it doesn't "suit" the conditions in a while loop when used with a parameter. I've recreated the snippet below, which causes the same error as my main program.

#include <math.h>
int main()
{
    double foo = 223.76;
    double bar = foo;
    while(fmod(bar,1.00) != 0)
    {
        bar += foo;
    }
    cout << bar << endl;
}

The above code should eventually stop and print out 5594, but instead it continues into the millions. Printing out the value of bar during each step does in fact show that it reaches the value of 5594 (it takes around 25 steps if you want to test it), so I can't figure out why it doesn't stop there.

Dwayne H
  • 235
  • 2
  • 11
  • 3
    Ouch, repeated sum of an imprecise value and comparing against an exact number, the Cardinal Sins of floating point programming. This will never work as is. Multiply everything by 100 for an easy solution. – Matteo Italia Aug 23 '16 at 05:12
  • `223.76` can only be represented exactly (with an ordinary C++ implementation) if it is a multiple of a power of 2. Is it? – Cheers and hth. - Alf Aug 23 '16 at 05:13
  • Well I did have it compared to 0.00 as well. The result ended up the same either way. – Dwayne H Aug 23 '16 at 05:13
  • Anyway, read up on What Every Scientist Should Know About Floating Point Arithmetic. – Cheers and hth. - Alf Aug 23 '16 at 05:14
  • The 223.76 comes from a time based event from one of the Topcoder problems. Basically it's the point during an exercise (in seconds) when 1% of the exercise time is finished. What I need is to find the first percentage when it's an exact number of seconds. – Dwayne H Aug 23 '16 at 05:15
  • 2
    Easier read-up: http://floating-point-gui.de/ – Matteo Italia Aug 23 '16 at 05:16
  • 3
    Then treat it as 22373, and check for when it's a multiple of 100. Easy peasy. ;-) – Cheers and hth. - Alf Aug 23 '16 at 05:17
  • @Cheersandhth.-Alf That worked perfectly. Just required a few extra lines of code before the while loop since I needed to use the doubles afterwards. – Dwayne H Aug 23 '16 at 05:23

1 Answers1

1

It is most likely a numerical issue. So it might be very close to 0 but not exactly equal to 0. So try while(fmod(bar,1.00) > 1e-10) instead.

grigor
  • 1,584
  • 1
  • 13
  • 25
  • I tried this but it ended up causing a infinite loop. A solution was found in the comments above, but thanks anyway! – Dwayne H Aug 23 '16 at 05:24