简体   繁体   中英

Floating point error in while loop in C++

int main()
 {
      float x = k ; // k is some fixed positive value 
      while(x>0)
           x-- ;
      return 0 ;
 }

Can above program go in infinite loop ?

Yes it's possible. Take the maximum float as an example.

As this code illustrates, for the biggest float m , m equals m - 1 :

#include <iostream>
#include <limits>

int main() {
    auto m = std::numeric_limits<float>::max();
    auto l = m;
    l--;
    std::cerr << (m == l) << "\n";
}

Demo: http://ideone.com/Wr9zdN

Therefore, with this start value, the loop will be infinite.

Why is that?

float has (as every other built-in type) a limited precision. To make x - 1 representable by a number other than x , the difference between the biggest number smaller than x must be less than 2.

Now let's calculate the difference between m , the maximum float and x , the biggest float, which is strictly less than m :

#include <iostream>
#include <cmath>
#include <limits>

int main() {
    auto m = std::numeric_limits<float>::max();
    std::cout << "float max: " << m << "\n";
    auto x = std::nextafter(m, 0.0f);
    std::cout << "biggest value less than max: " << x << "\n";
    auto d = m - x;
    std::cout << "the difference: " << d << "\n";
}

Demo: http://ideone.com/VyNgtE

Turns out, there is a huge gap of 2.02824e+31 between those two numbers. Far bigger than 1. 1 is simply too tiny to make a difference.

Yes it can. If k is FLT_MAX for example. There's not enough precision to handle such small distance between such big numbers.

#include <float.h>
#include <stdio.h>

int main()
{
    float a = FLT_MAX;
    float b = a - 1;
    printf("%.10f\n", a - b);

    return 0;
}

Output:

0.0000000000

I think it can, actually. If k is big enough rounding will devour your decrement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM