带有十进制值的for循环的增量

时间:2014-06-09 21:08:59

标签: c++ for-loop floating-point

首先让我说我已经检查了相关主题 问题是我想用小数步长制作一个for循环 我已经准备了波纹管代码来解决问题,但是它没有使用上面提到的步长

生成准确的数字
 float b;


   for ( double a=-0.2; a<=0.2 ; a+=0.01)// a = landa with an increment of 0.1

    {

        b = a * 100.0;
    a = ((int)b) / 100.0;

}

我想要的是在每次迭代中都有一个准确的数字,但是因为变量被定义为一个双倍,它接近​​它必须的值。( - 0.20000000001,-0.19000000002,....) 请让我知道如何解决这个问题&amp;代码有什么问题吗?

4 个答案:

答案 0 :(得分:14)

而不是:

for (double a = -0.2; a <= 0.2; a += 0.01)
{
    ...
}

使用整数循环索引并计算循环内的相应浮点值,例如

for (int i = -20; i <= 20 ; ++i) // a = -0.2 to 0.2 step 0.01
{
    const double a = i / 100.0;
    ...
}

答案 1 :(得分:2)

要使用精确小数进行计算,您可以使用像bdldfp::Decimal64这样的十进制浮点类:十进制浮点不要使用基数2哪些计算机擅长计算,而是基数10。结果他们的处理速度较慢(使用IBM的decNumber当前的实现并不是很好,但正在纠正使用英特尔的实现)。作为回报,十进制计算是准确的:

using namespace BloombergLP;
bdldfp::Decimal64 a(BDLDFP_DECIMAL64_DD(-0.2));
bdldfp::Decimal64 add(BDLDFP_DECIMAL64_DD(0.01));
bdldfp::Decimal64 end(BDLDFP_DECIMAL64_DD(0.2));
for (; a <= end; a += add) {
    std::cout << a << '\n';
}

可以使用C ++ 11特性(例如,使用_DD作为文字后缀)来实现更好的实现,但它也适用于C ++ 03编译器。我正致力于将十进制浮点类添加到C ++标准中(here是该提案的最新版本。)

使用二进制浮点时,例如double,您无法准确表示值。您可能会获得基于整数进行迭代的最接近的值,并在每次迭代中适当地划分:

for (int a(-20); a <= 20; ++a) {
    std::cout << (a / 100.0) << '\n';
}

直接使用double并在每次迭代中添加0.01时会出现一些舍入错误,这会增加先前值的不准确性。

答案 2 :(得分:1)

沿着这些方向使用:

double min = -0.2;
double max = +0.2;
int N = 40;
for(int i=0; i<=N; i++) {
    double a = min + static_cast<double>(i)*((max - min)/static_cast<double>(N));
    double b = a * 100.0;
    ...
}

答案 3 :(得分:1)

这句话也是一个潜在的问题:

    a = ((int)b) / 100.;

因为(int)b将b截断为零。例如,如果b == 101.9999999999,那么(int)b将产生101(而不是102)。要坚持原始概念,请尝试以下方法:

double a;
int b;
    for(a = -.2; a <= .2; a += .01){
        b = (int)(a*100. + ((a < -0.005)? -.5 : .5));
        a = (double)b / 100.;
    }

注意,(a <-005)是对负数a的检查,误差幅度为步进率的1/2。

正如其他人发布的那样,使用整数表示循环并设置&#39; a&#39;基于整数将是一个更好的解决方案。