1
#include <iostream>
#include <stdlib.h>
#include <iomanip>

using namespace std;

int main ()
{
    double x = 10000;
    double y = x*0.05;

    if(500 == 400+100)
        cout<<"asd1"<<endl;

    if(500 == 0.05*x)
        cout<<"asd2"<<endl;

    if(500 == y)
        cout<<"asd3"<<endl;

}

The above code should print all three asd1, asd2, asd3. As predicted, Visual Studio printed all three. However, my Code Blocks wouldn't. It did not print asd2. How do I solve this?

IKavanagh
  • 6,089
  • 11
  • 42
  • 47
ZeeJ
  • 23
  • 6
  • change the variable x to int – The Apache Oct 30 '15 at 04:53
  • 2
    It might be worth double-checking CodeBlocks compilation options re. floating-point calculus – Daniel Strul Oct 30 '15 at 04:59
  • 5
    You may be getting 499.99999999 or 500.000001 or something similar which is not 500. Floating point is difficult to use in comparisons. Give this a read: http://stackoverflow.com/questions/21895756/why-are-floating-point-numbers-inaccurate – user4581301 Oct 30 '15 at 05:40

2 Answers2

1

Change it to :

int main ()
{
    int x = 10000;
    int y = x*0.05;

    if(500 == 400+100)
        cout<<"asd1"<<endl;

    if(500 == int(0.05*x))
        cout<<"asd2"<<endl;

    if(500 == y)
        cout<<"asd3"<<endl;

}

and try to read this: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

hfhc2
  • 4,182
  • 2
  • 27
  • 56
Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160
-1

Pedantic note: Code::Blocks isn't a compiler, so the "weird logic" isn't within it, but within whatever compiler you're using (probably gcc/g++).

With the version of g++ in my installation (4.8.4), I can replicate the problem by compiling without any optimisation. Using any of the -O options results in the expected output.

Here's the full output of g++ --version on my system:

g++ (i686-posix-sjlj-rev0, Built by MinGW-W64 project) 4.8.4

The following version of g++ gives the expected output, regardless of the optimisation setting:

g++ (Debian 4.9.2-10) 4.9.2

So: you could see if you can upgrade the compiler which may result in different behaviour, or always compile with at least -O. In Code::Blocks this is listed under Compiler settings, Compiler flags, Optimization options, as "Optimize generated code (for speed)". Any of the optimization levels appear to give the desired output, even optimising for size instead of speed.

Also, as user4581301 commented, you normally want to avoid performing exact equality tests on floating point numbers, but instead test if the value lies within a specific range. Or, explicitly cast the result to an integer type before the comparison as Humam Helfawi suggests. Even though the optimisation setting seems to "fix" this particular case, there may be others that it doesn't, or for which the unoptimized code produces the desired result but the optimized code does not.

notmyfriend
  • 245
  • 1
  • 7
  • The problem isn't the optimization. Regardless of optimization levels (including none), a correct program should not change observable behavior. The problem is the rounding of the floating points numbers (or rather him not accounting for them). – bolov Oct 30 '15 at 09:22
  • It's related to the optimisation. What I think is happening is that the un-optimised code is being compiled pretty much as-is, so you get floating-point innaccuracies. The optimised code is being pre-calculated by g++ (since there's nothing that actually requires evaluation at run-time), and it's doing it with higher precision than standard floating-point math allows. – notmyfriend Nov 05 '15 at 09:36