使用 float / double 作为循环变量

rah*_*hul 0 c++ computer-science

在 x64 架构上运行,Visual Studio 2013 Windows 8.1

我正在尝试运行一个使用浮点数作为循环变量的循环,问题是在增量操作期间十进制值丢失。

例如:

float incrementValue = 360 / 14;
for (float i = 0; i <= 360; i = i + incrementValue)
{
    cout << endl << " I " << i;
}
Run Code Online (Sandbox Code Playgroud)

我需要 i >= 360 的值。但它停在 350 处。由于 360/14 =25.7142857 但看起来增量的步长为 25 。如果我对任何整数做同样的事情,它都可以正常工作,这个问题仅适用于 xx.yyyy 形式的任何数字

我尝试查找有关此问题的各个网站,但找不到任何可以帮助我/回答我的问题的内容。

pax*_*blo 5

您在这里遇到三个问题(两个相关),所有这些问题都可能有所贡献。

首先,浮点比较通常是不明智的,因为虽然您可能认为360,但实际上可能是359.999999942

第二个是随着时间的推移,误差会逐渐增加。每次您添加一个像0.99认为的那样的数字时1,错误都会累积。

根据您使用的值,这些错误可能会很小,但无论如何您都应该意识到它们。如果您开始处理大量数字,您很快就会发现问题。


最后一个不相关的问题是360 / 14整数除法,它会给你一个整数结果,25而不是25.714285714

您可以通过确保其中一个值是浮点数来解决最后一个问题:

float incrementValue = float(360) / 14;
Run Code Online (Sandbox Code Playgroud)

但这并不能解决前两个问题,它们在某些时候会困扰你。

要解决这个问题,您最好坚持使用整数(无论如何对于这个简单的情况)并在最新可能的情况下转换为浮点数:

#include<iostream>
int main (void) {
    int incrementValue = 360;
    for (int i = 0; i <= 360 * 14; i = i + incrementValue)
        std::cout << " I " << float(i) / 14 << '\n';
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这给你:

 I 0
 I 25.7143
 I 51.4286
 I 77.1429
 I 102.857
 I 128.571
 I 154.286
 I 180
 I 205.714
 I 231.429
 I 257.143
 I 282.857
 I 308.571
 I 334.286
 I 360
Run Code Online (Sandbox Code Playgroud)