浮动比较给出不同的结果
看下面两个代码,告诉我答案差异很大的原因。
#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,则会打印 else 的语句:
#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;
}
那么,为什么当我们只更改一位数字时,输出会发生变化呢?
Look at the following two codes, and tell me the reason why answers vary a lot.
#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;
}
And if we change 0.9 to 0.8, then else's statement is printed:
#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;
}
So why this output changes when we just change a single digit?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
此错误是由于浮点精度造成的,并且因为您正在将
float
类型与double
值进行比较。尝试将其与浮点文字进行比较:if(a<0.8f)
我建议您阅读相应的维基百科文章,它详细解释了您的错误发生的原因。
This error is due to floating point accuracy and because you are comparing a
float
type with adouble
value. Try to compare it versus floating point literals:if(a<0.8f)
I suggest you read the according wikipedia article, it explains in detail why your error happens.
文字
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 上查看数字的单/双表示形式。
The literals
0.9
and0.8
have typedouble
. Since both values cannot be represented exactly, they will in fact be0.9000000000000000222...
and0.8000000000000000444...
.When stored in the
float
(single precision) variablea
they will be converted to single and become even more inaccurate:0.89999997...
and0.8000000119...
.For the comparison with the literal
double
value they are converted back todouble
retaining the more inaccurate value.As you can see from the numbers above, the comparison yields different results for
0.9
and0.8
.All this is assuming your platform has IEEE754 floats which is most probably the case.
You can see single/double representations of numbers at www.binaryconvert.com.
您必须知道浮点是如何工作的。
浮点数使用 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,结果是精确的并且可以用 2 的幂表示。您可以通过打开
python
提示符来尝试此操作。尝试输入几个数字,最终会以...99999999
结尾。You have to know how floating points works.
Floating points are represented by using powers of two, each digit is used to represent
2^-x
where X is the n-th digit.For example,
0.011
(binary) would be2^-2 + 2^-3
, which is0.25 + 0.125 = 0.375
Now try to represent
0.9
. You are in trouble, since no power of two to represent it. The value this is represented in 32-bits and probably 64-bits machines will give a result slightly smaller than 0.9,whereas for 0.8 the result is precise and representable by powers of two.You can try this out by opening a
python
prompt. Try and type a few numbers, eventually one will end with...99999999
.根据C标准:
该标准可在此处找到。
According to the C Standard:
The standard can be found here.
这是由于舍入错误造成的,要查看您正在使用的值,请在 if 之前插入 printf:
This is due to rounding errors, to see the value of that you are using insert a printf before the if:
首先,正如其他人提到的,在使用
float
时使用诸如0.8f
之类的值。此外,由于 FPU 中此操作的精度,您应该避免进行浮点
==
比较。对我来说最有效的方法是定义一个边距,比如说1e-6f
(或者根据您的应用程序需要的精度),而不是这样:您可以编写:
您可以编写一个函数(如果你是 c++ 粉丝)或宏(如果你是 ac 粉丝(这里是 -1s))会为你完成此操作。
First of all, as others mentioned, use values like
0.8f
when working withfloat
s.Also, floating point
==
comparison is something you would want to avoid because of the precision of this operation in the FPU. What always worked best for me, was to define a margin, let's say1e-6f
(or the precision you need based on your application) and instead of this:you write:
You could write a function (if you are a c++ fan) or macro (if you are a c fan (here comes the -1s)) that does this for you.
试试这个:
用“if(a<0.9f)”代替“if(a<0.9)”进行比较
Try this:
Instead of "if(a<0.9)" compare using "if(a<0.9f)"