-1

In this code, the value of rr is working properly only when i am using the printf statement, otherwise the code is entering into the while loop even if rr is actually an integer value, for example rr = 2.0.

My full code here

    double rr = log(c)/log(2);
    printf("Current value of rr is %lf\n",rr);


    while(!(rr == (int)rr))
    {
        printf("hung in loop with c = %d\n",c);

            if(c % 2 == 0)
                c = c/2;
            else
                c = (c-1)/2;
            rr = log(c)/log(2);
            cc++;

    }    

This is the weirdest problem i have ever faced. The question is codechef august challenge problem 1.

lurker
  • 56,987
  • 9
  • 69
  • 103
Saurav Mukherjee
  • 177
  • 1
  • 16
  • 1
    One problem might be that you're doing [floating point equality comparison](http://stackoverflow.com/q/17333/3425536). – Emil Laine Aug 09 '15 at 11:06
  • 1
    When `rr` is `2.0` you now that it is likely that it's not *exactly* `2.0` in binary, right? It might be `1.99999997` or `2.00000012`. Floating point values are not exactly precise. – lurker Aug 09 '15 at 11:07
  • but just ading a printf statement solves the problem! – Saurav Mukherjee Aug 09 '15 at 11:08
  • @SauravMukherjee Not my vote but one reason could be that the title is not very descriptive. – Emil Laine Aug 09 '15 at 11:08
  • 1
    @SauravMukherjee If adding a `printf` makes it work then you've almost certainly got undefined behavior somewhere. – Emil Laine Aug 09 '15 at 11:09
  • Do a couple of things. Search Stackoverflow for "floating point precision". There are numerous problems posted in that area. Also, read, [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – lurker Aug 09 '15 at 11:10
  • @zenith, can u explain a little bit further, or any articles will be much appreciated. – Saurav Mukherjee Aug 09 '15 at 11:10
  • @SauravMukherjee Don't be newbie, instead [RTFM](http://stackoverflow.com/help/how-to-ask). – Emil Laine Aug 09 '15 at 11:11
  • alright, will keep it in mind from next time. ty – Saurav Mukherjee Aug 09 '15 at 11:14
  • 2
    As an aside, in C, there's an inequality operator. So instead of `!(a == b)` you just use `a != b`. As noted above, however, *exact* comparison of float values with other values is not generally going to do what you expect due to resolution of the fractional part representation in the machine. – lurker Aug 09 '15 at 11:15
  • Thank guys, i kept the difference range within the limit of 0.001 and it works now. However, it was still a pretty weird problem to have! :p – Saurav Mukherjee Aug 09 '15 at 11:20
  • @lurker, i know. But what's the difference between !(a == b) and (a != b) ? – Saurav Mukherjee Aug 09 '15 at 11:21
  • Semantically they mean the same thing. If the first case, you are testing for equality and logically negating the result. In the second, you are testing for inequality. – lurker Aug 09 '15 at 11:22
  • When `rr` is a `double`, when you compare `rr = (int)rr`, C is going to cast the `rr` on the right to an `int` and it will truncate it. So it might result in an integer value of `1` or of `2` depending upon whether `rr` value of 2.0 is really 1.999999something, or 2.000000something. Then, to compare with `rr` again, it will take that result of `1` or `2` and promote it (recast it) to a `double` to compare like types. I'm not sure exactly what you want to achieve, but this construct is most likely not doing what you want. – lurker Aug 09 '15 at 11:28

1 Answers1

3

As mentioned in lurker's comment, this is not doing what you expect:

while(!(rr == (int)rr))

A better method would be:

while((rr - floor(rr)) > .0001)

This avoids casting and accounts for the fact that floating point is not always an exact representation.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Can someone delete the post, because the original code is present her, and i don't want someone(a random guy) to copy paste my code as a result of which i might be disqualified. – Saurav Mukherjee Aug 09 '15 at 12:26