cplexilog

Issue when comparing two IloNum values


The following snippet of code:

IloNum i = 2*0.6 + 3*0.4 + 0.6 - 0.4 + 1 + 0.6 - 0.4 + 1;
IloNum j = 4.8;
cout << "i=" << i << ", j=" << j << ", (i>j)=" << (i > j) << endl;

has the following output:

i=4.8, j=4.8, (i>j)=1

Have I overlooked some details in the documentation or is this a bug?


Solution

  • You should remember that as soon as you do some float operations you have some tiny errors.

    If I rewrite your model in OPL

    float i = 2*0.6 + 3*0.4 + 0.6 - 0.4 + 1 + 0.6 - 0.4 + 1;
    float j = 4.8;
    
    execute
    {
    writeln("i=" , i , ", j=" ,j ,", (i>j)=" , (i > j) );;
    }
    
    float i2=i-4.8;
    float j2=j-4.8;
    
    execute
    {
    writeln("i2=",i2);
    writeln("j2=",j2);
    }
    

    then I get

    i=4.8, j=4.8, (i>j)=true
    i2=8.881784197e-16
    j2=0
    

    which shows the tiny imprecision that leads to what looks like a paradox

    And let me underline that

        float i = 2*6 + 3*4 + 6 - 4 + 10 + 6 - 4 + 10;
    float j = 48;
    
    execute
    {
    writeln("i=" , i , ", j=" ,j ,", (i>j)=" , (i > j) );;
    }
    
    float i2=i-48;
    float j2=j-48;
    
    execute
    {
    writeln("i2=",i2);
    writeln("j2=",j2);
    }
    

    gives

    i=48, j=48, (i>j)=false
    i2=0
    j2=0