我在本书中被问到一个非常简单的问题来编写以下程序的输出 -
#include<stdio.h>
int main()
{
float i=1.1;
while(i==1.1)
{
printf("%f\n",i);
i=i-0.1;
}
return 0;
}
现在我已经读过我可以使用浮点数作为循环计数器但不建议我学习。现在,当我在gcc中运行这个程序时,即使逻辑完全正确并且I的值应该打印一次,我也没有输出。我尝试打印i的值,它给了我1.100000的结果。所以我不明白为什么价值不被打印?
答案 0 :(得分:12)
在大多数C实现中,使用IEEE-754二进制浮点,程序中会发生以下情况:
1.1
将转换为double
。由于二进制浮点不能准确表示此值,因此结果是最接近的可表示值1.100000000000000088817841970012523233890533447265625。float i=1.1;
将值转换为float
。由于float
的精度低于double
,因此结果为1.10000002384185791015625。在比较i==1.1
中,float
1.10000002384185791015625转换为double
(不更改其值),并与1.100000000000000088817841970012523233890533447265625进行比较。由于它们不相等,结果是错误的。
答案 1 :(得分:5)
数量11/10无法在二进制浮点中精确表示,它具有不同的近似值double
和float
。
源代码中的常量1.1
是{10}的近似值double
。由于i
的类型为float
,因此最终会包含float
的{{1}}近似值。
撰写1.1
或将while (i==1.1f)
声明为i
,您的计划即可运作。
答案 2 :(得分:2)
Comparing floating point numbers: 1
浮点数学并不准确。像
0.2
这样的简单值无法使用二进制浮点数精确表示,浮点数的精度有限意味着操作顺序的微小变化可能会改变结果。不同的编译器和CPU架构以不同的精度存储临时结果,因此结果将根据环境的详细信息而有所不同。如果您进行计算,然后将结果与某些预期值进行比较,那么您很可能无法获得预期的结果。换句话说,如果你进行计算然后进行比较:
if (result == expectedResult)
那么比较不太可能。如果比较结果为真,那么它可能不稳定 - 输入值,编译器或CPU的微小变化可能会改变结果并使比较结果为假。
简而言之:
1.1
无法准确表示二进制浮点数。这就像十进制10/3
的十进制表示形式3.333333333..........
我建议你阅读文章What Every Computer Scientist Should Know About Floating-Point Arithmetic。
<子> 1。对于鼓励初学者程序员在浮点比较中使用==
的专家
答案 3 :(得分:1)
因为我不完全是1.1。
如果你要测试一个浮点,你应该在while(i-1.1 < SOME_DELTA)
的行上做一些事情,其中delta是相等足够好的阈值。