Menu

#667 n<=-0.5 for rounding doesn't work for -0.5 only for -0.6. <= interpreted as <

v1.0 (example)
closed-invalid
nobody
None
5
2017-09-22
2017-09-15
No

incorrect output because of bad logic for <=:

x=-1:x<=-0.5=1
x=-0.9:x<=-0.5=1
x=-0.8:x<=-0.5=1
x=-0.7:x<=-0.5=1
x=-0.6:x<=-0.5=1
x=-0.5:x<=-0.5=0  (this should be 1)
x=-0.4:x<=-0.5=0
x=-0.3:x<=-0.5=0
x=-0.2:x<=-0.5=0
x=-0.1:x<=-0.5=0
x=5.55112e-017:x<=-0.5=0
x=0.1:x<=-0.5=0
x=0.2:x<=-0.5=0
x=0.3:x<=-0.5=0
x=0.4:x<=-0.5=0
x=0.5:x<=-0.5=0
x=0.6:x<=-0.5=0
x=0.7:x<=-0.5=0
x=0.8:x<=-0.5=0
x=0.9:x<=-0.5=0
1 Attachments

Discussion

  • Doug Semler

    Doug Semler - 2017-09-15

    Welcome to the world of floating point on a computer.

    Oh, and floating point loop conditions are never a good idea.

     
  • Jim Michaels

    Jim Michaels - 2017-09-21

    run this code:

    #include <iostream>
    #include <cstdint>
    int main() {
    for (double w=-1.0; w <= 1.0; w+=0.1) {
        std::cout<<"w="<<w<<":w<=-0.5="<<(w<=-0.5)<<std::endl;
    }
    for (long double x=-1.0; x <= 1.0; x+=0.1) {
        std::cout<<"x="<<x<<":x<=-0.5="<<(x<=-0.5)<<std::endl;
    }
    for (int y=-3; y <= 3; y+=1) {
        std::cout<<"y="<<y<<":y<=2="<<(y<=2)<<std::endl;
    }
    for (int64_t z=-3; z <= 3; z+=1) {
        std::cout<<"z="<<z<<":z<=2="<<(z<=2)<<std::endl;
    }
    return 0;
    }
    

    apparently only <= for long double gives wrong results.

    w=-1:w<=-0.5=1
    w=-0.9:w<=-0.5=1
    w=-0.8:w<=-0.5=1
    w=-0.7:w<=-0.5=1
    w=-0.6:w<=-0.5=1
    w=-0.5:w<=-0.5=1
    w=-0.4:w<=-0.5=0
    w=-0.3:w<=-0.5=0
    w=-0.2:w<=-0.5=0
    w=-0.1:w<=-0.5=0
    w=-1.38778e-016:w<=-0.5=0
    w=0.1:w<=-0.5=0
    w=0.2:w<=-0.5=0
    w=0.3:w<=-0.5=0
    w=0.4:w<=-0.5=0
    w=0.5:w<=-0.5=0
    w=0.6:w<=-0.5=0
    w=0.7:w<=-0.5=0
    w=0.8:w<=-0.5=0
    w=0.9:w<=-0.5=0
    w=1:w<=-0.5=0
    x=-1:x<=-0.5=1
    x=-0.9:x<=-0.5=1
    x=-0.8:x<=-0.5=1
    x=-0.7:x<=-0.5=1
    x=-0.6:x<=-0.5=1
    x=-0.5:x<=-0.5=0
    x=-0.4:x<=-0.5=0
    x=-0.3:x<=-0.5=0
    x=-0.2:x<=-0.5=0
    x=-0.1:x<=-0.5=0
    x=5.55112e-017:x<=-0.5=0
    x=0.1:x<=-0.5=0
    x=0.2:x<=-0.5=0
    x=0.3:x<=-0.5=0
    x=0.4:x<=-0.5=0
    x=0.5:x<=-0.5=0
    x=0.6:x<=-0.5=0
    x=0.7:x<=-0.5=0
    x=0.8:x<=-0.5=0
    x=0.9:x<=-0.5=0
    y=-3:y<=2=1
    y=-2:y<=2=1
    y=-1:y<=2=1
    y=0:y<=2=1
    y=1:y<=2=1
    y=2:y<=2=1
    y=3:y<=2=0
    z=-3:z<=2=1
    z=-2:z<=2=1
    z=-1:z<=2=1
    z=0:z<=2=1
    z=1:z<=2=1
    z=2:z<=2=1
    z=3:z<=2=0
    

    you should look carefully before commenting.

     
  • Doug Semler

    Doug Semler - 2017-09-21

    You really need to start by understanding how floating point works. You need to realize your code is flawed, right? Don't tell me to look before commenting. I completely understand what has happened in your code. The values you are comparing are INEXACT, leading to rounding and error accumulation.

    If you want to see what's really happening, add a setprecision manipulator to the stream:

    #include <iostream>
    #include <iomanip>
    typedef long double ld;
    int main() {
    ld x,y=-0.5,inc=0.1;
    for (x=-1.0; x <= 1.0; x+=0.1) {
            std::cout<< std::setprecision(40) << "x="<<x<<":x<=-0.5="<<(x<=-0.5)<<std::endl;
    }
    return y<=-0.5?0:1;
    }
    
    $ ./a.exe
    x=-1:x<=-0.5=1
    x=-0.8999999999999999944488848768742172978818:x<=-0.5=1
    x=-0.7999999999999999888977697537484345957637:x<=-0.5=1
    x=-0.6999999999999999833466546306226518936455:x<=-0.5=1
    x=-0.5999999999999999777955395074968691915274:x<=-0.5=1
    x=-0.4999999999999999722444243843710864894092:x<=-0.5=0
    x=-0.399999999999999966693309261245303787291:x<=-0.5=0
    x=-0.2999999999999999611421941381195210851729:x<=-0.5=0
    x=-0.1999999999999999555910790149937383830547:x<=-0.5=0
    x=-0.09999999999999995003996389186795568093657:x<=-0.5=0
    x=5.5511151231257827021181583404541015625e-017:x<=-0.5=0
    x=0.1000000000000000610622663543836097232997:x<=-0.5=0
    x=0.2000000000000000666133814775093924254179:x<=-0.5=0
    x=0.3000000000000000721644966006351751275361:x<=-0.5=0
    x=0.4000000000000000777156117237609578296542:x<=-0.5=0
    x=0.5000000000000000832667268468867405317724:x<=-0.5=0
    x=0.6000000000000000888178419700125232338905:x<=-0.5=0
    x=0.7000000000000000943689570931383059360087:x<=-0.5=0
    x=0.8000000000000000999200722162640886381269:x<=-0.5=0
    x=0.900000000000000105471187339389871340245:x<=-0.5=0
    

    Do you get it now?

     
  • Doug Semler

    Doug Semler - 2017-09-21

    P.S. Close this as yet again NOT A BUG

     
  • Kai Tietz

    Kai Tietz - 2017-09-21
    • status: open --> closed-invalid
     

Log in to post a comment.