使用float / double作为循环变量

时间:2015-02-06 09:12:57

标签: c++ computer-science

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

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

例如:

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

我需要i&gt; = 360的值。但它停在350。 自360/14 = 25.7142857 但看起来增量是25步。 如果我对任何整数做同样的事情它工作正常,这个问题只有xx.yyyy的任何形式

我尝试在这个问题上查找各种网站,但我无法找到任何可以帮助我/回答我的问题。

7 个答案:

答案 0 :(得分:3)

360 / 14将为您提供整数结果。试试360.0 / 14.0

答案 1 :(得分:3)

这里有三个问题(两个相关),所有这些都可能有所帮助。

首先,浮点比较通常是不明智的,因为你可能认为你有360,它实际上可能是359.999999942

第二,随着时间的推移,不准确性会逐渐增加。每当您添加{em>认为为0.99的{​​{1}}这样的数字时,错误就会累积。

使用您正在使用的值,这些错误可能会保持很小但无论如何您都应该了解它们。如果您开始处理大量数字,您很快就会发现问题。


最终且无关的问题是1整数除法,它会给出整数结果360 / 14而不是25

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

25.714285714

但那不会修复前两个,在某些时候咬你。

要修复你最好坚持使用整数(无论如何都是这个简单的情况)并在最新的可能实例中转换为浮点数:

float incrementValue = float(360) / 14;

给你:

#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;
}

答案 2 :(得分:2)

很难得到'i = 360',因为'i = 360.0000001'将无法通过测试并且准确地获得'360'会很棘手。计算机上的浮点很难,而且很容易陷入困境。

最好尽可能使用整数: -

int num_steps = 14;

for (int i = 0 ; i <= num_steps ; ++i)
{
  float value = 360.0f * i / num_steps;
  // use value
}

在循环中使用'&lt; ='意味着你得到'值'为'360',因为'i / num_steps'是1。话虽如此,由于浮点错误,您可能无法得到'360.0f'。

答案 3 :(得分:1)

从分区浮点类型中生成操作数:

 float incrementValue = 360.f / 14.f;

答案 4 :(得分:0)

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

答案 5 :(得分:0)

如果你知道迭代次数,那么使用float来控制循环不是一个好主意,因为浮点数并不精确。

事实上,使用浮点控制任何循环是一个坏主意,不使用公差(这将取决于机械精度),以允许潜在的舍入误差。

在这种情况下,您知道迭代次数,因此像这样的循环可以解决问题。

int num_steps = 14
float factor = 360.0/num_steps;

for (int i = 0; i < num_steps; ++i)
{
    std::cout << "\nI" << (i*factor);
}

答案 6 :(得分:0)

当我真的想在循环中使用浮点数时,我会更改上限以确保连续浮点错误没有错误。

float x_min = 0.;
float x_max = 360.;
int N_steps = 14;
float x_step = (x_max - x_min) / N_steps;

for (float x = x_min; x <= x_max + x_step / 2; x += x_step)
{
    // do stuff
}

虽然这可以确保我每个步骤都正确,但如果有大量步骤,精度问题就会增加。在这种情况下,使用整数循环变量并每次计算相应的浮点数。然后我只有一次浮点错误而不是总计的14(或一百万)次。