Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Floating point error in while loop in C++

Tags:

c++

c

compilation

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

Can above program go in infinite loop ?

like image 997
Hellboy Avatar asked Oct 17 '13 09:10

Hellboy


3 Answers

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.

like image 142
stefan Avatar answered Oct 19 '22 12:10

stefan


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
like image 44
detunized Avatar answered Oct 19 '22 10:10

detunized


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

like image 4
Ivan Ishchenko Avatar answered Oct 19 '22 11:10

Ivan Ishchenko