简体   繁体   English

C ++中while循环中的浮点错误

[英]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 : 如此代码所示,对于最大的浮点数mm等于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 演示: 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. float (与其他所有内置类型一样)的精度有限。 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. 为了使x - 1由比其它的数表示的x ,最大的数小于之间的差x必须小于2。

Now let's calculate the difference between m , the maximum float and x , the biggest float, which is strictly less than m : 现在,让我们计算的区别m的最大浮动和, x ,最大的浮动,这是严格小于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 演示: http//ideone.com/VyNgtE

Turns out, there is a huge gap of 2.02824e+31 between those two numbers. 事实证明,这两个数字之间存在2.02824e+31的巨大差距。 Far bigger than 1. 1 is simply too tiny to make a difference. 远远大于1. 1太小而无法发挥作用。

Yes it can. 是的,它可以。 If k is FLT_MAX for example. 例如,如果kFLT_MAX 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. 如果k足够大,四舍五入将吞噬你的减量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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