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个数字?
我已经尝试了一种循环遍历浮点数的替代方法,其中我将循环变量缩放为整数,并打印循环变量的结果除以使用的缩放.但也许有更好的方法......
double在for循环中使用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.
| 归档时间: |
|
| 查看次数: |
78 次 |
| 最近记录: |