循环在C中的一系列浮点数

Pav*_*yer 3 c floating-point for-loop

我正在尝试用C编写程序来完成以下任务.

输入:三个双精度数,a,b和c.

输出:从b到a的所有数字,可以通过c的减量达到.

这是一个简单的程序(filename:range.c).

#include <stdlib.h>
#include <stdio.h>

int main()
{
    double high, low, step, var;
    printf("Enter the <lower limit> <upperlimit> <step>\n>>");
    scanf("%lf %lf %lf", &low, &high, &step);
    printf("Number in the requested range\n");
    for (var = high; var >= low; var -= step)
        printf("%g\n", var);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然而,对于某些输入,for循环表现得相当奇怪.例如,以下内容.

10-236-49-81:stackoverflow pavithran$ ./range.o 
Enter the <lower limit> <upperlimit> <step>
>>0.1 0.9 0.2
Number in the requested range
0.9
0.7
0.5
0.3
10-236-49-81:stackoverflow pavithran$ 
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么循环在var = 0.1时退出.而对于另一个输入,它的行为与预期的一样.

10-236-49-81:stackoverflow pavithran$ ./range.o 
Enter the <lower limit> <upperlimit> <step>
>>0.1 0.5 0.1
Number in the requested range
0.5
0.4
0.3
0.2
0.1
10-236-49-81:stackoverflow pavithran$ 
Run Code Online (Sandbox Code Playgroud)

如果在第一种情况下奇怪的行为与数字精度有关吗?

如何确保范围始终包含楼层((高 - 低)/步)+ 1个数字?

我已经尝试了一种循环遍历浮点数的​​替代方法,其中我将循环变量缩放为整数,并打印循环变量的结果除以使用的缩放.但也许有更好的方法......

Bat*_*eba 5

doublefor循环中使用a 作为计数器需要非常仔细地考虑.在许多情况下,最好避免.

我相信你知道并非所有十进制精确数字都是精确的二进制浮点数.事实上,对于IEEE754浮点数,只有二元有理数.所以0.5是,但0.4,0.3,0.2和0.1不是.

最接近double0.2的IEEE754浮点数实际上略大0.200000000000000011102230246251565404236316680908203125.

在你的情况下,从0.9重复减去这个数字最终导致一个数字,其第一个有效数字a将成为一个数字,其第一个重要数字是a - 3:你的bug然后表现出来.

简单的补救方法是使用整数,每次减1,并使用缩放输出step.