请看以下两个代码,并告诉我答案变化很大的原因。
#include<stdio.h>
int main() {
float a = 0.9;
if(a<0.9)
printf("hi"); // This will be the answer
else
printf("bye");
return 0;
}
如果我们将0.9更改为0.8,则会打印其他语句:
#include<stdio.h>
int main() {
float a = 0.8;
if(a<0.8)
printf("hi");
else
printf("bye");//this will be the answer
return 0;
}
那么,当我们改变一个数字时,为什么这个输出会改变?
答案 0 :(得分:10)
此错误是由浮点精度引起的,因为您要将float
类型与double
值进行比较。尝试将其与浮点文字进行比较:if(a<0.8f)
我建议您阅读相应的wikipedia article,它会详细解释您的错误发生的原因。
答案 1 :(得分:5)
文字0.9
和0.8
的类型为double
。由于两个值都无法准确表示,因此它们实际上是0.9000000000000000222...
和0.8000000000000000444...
。
当存储在float
(单精度)变量a
中时,它们将转换为单个变得更加不准确:0.89999997...
和0.8000000119...
。
为了与文字double
值进行比较,它们会转换回double
,保留更准确的值。
从上面的数字可以看出,比较会为0.9
和0.8
产生不同的结果。
所有这一切都假设您的平台具有IEEE754浮动,这很可能就是这种情况。
您可以在www.binaryconvert.com看到数字的单/双表示。
答案 2 :(得分:1)
您必须知道浮点的工作原理。
浮点数用2的幂表示,每个数字用于表示2^-x
,其中X是第n个数字。
例如,0.011
(二进制)为2^-2 + 2^-3
,即0.25 + 0.125 = 0.375
现在尝试代表0.9
。你有麻烦,因为没有两个人的力量代表它。在32位且可能是64位机器中表示的值将给出略小于0.9的结果,而对于0.8,结果是精确的并且可以用两个的幂表示。
您可以通过打开python
提示进行尝试。尝试输入一些数字,最后会以...99999999
结尾。
答案 3 :(得分:1)
根据C标准:
6.3.1.5真正的浮动类型
1)当float被提升为double或long double时,或者是double 提升为长双,其价值不变。
2)当双人被降级为浮动时,长双人被降级为双人 浮动,或以更高的精度和范围表示的值 它的语义类型(见6.3.1.8)所要求的是明确的 转换为语义类型,如果转换的值可以 完全代表新类型,它没有变化。如果值 被转换的范围是可以表示的值,但是 无法准确表示,结果要么是最接近的 或最接近的较低可表示值,选择在 实现定义的方式。如果转换的值在外面 可以表示的值范围,行为未定义。
标准可以在 here 找到。
答案 4 :(得分:0)
首先,正如其他人所提到的,在使用0.8f
时使用float
之类的值。
此外,由于FPU中此操作的精确性,您需要避免浮点==
比较。对我来说最有效的方法是定义一个保证金,假设1e-6f
(或根据你的应用需要的精度),而不是:
if (LHS == RHS)
你写道:
if (LHS-RHS < MARGIN && RHS-LHS < MARGIN)
你可以编写一个函数(如果你是一个c ++粉丝)或宏(如果你是一个粉丝(这里是-1s)),它会为你做这个。
答案 5 :(得分:0)
这是由于舍入错误,要查看您在if之前使用插入printf的值:
printf("a=%f\n", a);
答案 6 :(得分:-1)
试试这个:
使用“if(a&lt; 0.9f)”而不是“if(a <0.9)”进行比较