C++ 浮点比较给出了不同的结果
请看以下两个代码,并告诉我答案差异很大的原因C++ 浮点比较给出了不同的结果,c++,c,floating-point,C++,C,Floating Point,请看以下两个代码,并告诉我答案差异很大的原因 #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; } #包括 int main(){ 浮点数a=0.9; if(a此错误是由于浮点精度,以及您正在将浮点类型与双精度值
#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;
}
#包括
int main(){
浮点数a=0.9;
if(a此错误是由于浮点精度,以及您正在将浮点
类型与双精度
值进行比较。请尝试将其与浮点文字进行比较:if(a您必须知道浮点如何工作
浮点数用2的幂表示,每个数字表示2^-x
,其中x是第n位
例如,0.011
(二进制)将是2^-2+2^-3
,即0.25+0.125=0.375
现在尝试表示0.9
。您遇到了麻烦,因为没有2的幂来表示它。用32位和可能64位表示的值机器将给出略小于0.9的结果,而对于0.8,结果是精确的,可以用2的幂来表示
您可以通过打开一个python
提示符来尝试这一点。尝试并键入一些数字,最终一个数字将以..9999999
结尾。首先,正如其他人提到的,在使用float
s时,使用0.8f
等值
此外,浮点==
比较是您希望避免的事情,因为FPU中此操作的精度。对我来说,最有效的方法是定义一个边距,比如1e-6f
(或根据应用程序需要的精度),而不是:
if (LHS == RHS)
你写道:
if (LHS-RHS < MARGIN && RHS-LHS < MARGIN)
if(LHS-RHS
你可以写函数(如果你是C++风扇)或者宏(如果你是C扇子(这里是-1s))这就为您做了。
文本0.9
和0.8
具有类型double
。由于无法准确表示这两个值,因此它们实际上将是0.900000000000000222…
和0.8000000000000444…
当存储在float
(单精度)变量a
中时,它们将被转换为单精度,变得更加不准确:0.899997…
和0.800000119…
为了与文本double
值进行比较,它们被转换回double
以保留更不准确的值
从上面的数字可以看出,0.9
和0.8
的比较结果不同
所有这些都是假设您的平台有IEEE754浮动,这很可能是事实
您可以在中看到数字的单/双表示。尝试以下方法:
而不是“如果(a根据C标准:
6.3.1.5实际浮浆类型
1) 当浮点数提升为double或long double时,或者
提升为长双精度,其值不变
2) 当双精度降级为浮动时,长双精度降级为双精度
或浮点,或以更高精度和范围表示的值
其语义类型(见6.3.1.8)明确要求
转换为其语义类型,前提是要转换的值可以
在新类型中精确表示,它保持不变。如果
正在转换的值在可表示的值范围内,但
无法精确表示,结果可能是最接近的较高值
或最近的较低代表值,在
实施方式定义。如果转换的值在外部
可以表示的值的范围,行为是不确定的
可以找到标准值这是由于舍入错误,要查看正在使用的值,请在if之前插入printf:
printf("a=%f\n", a);
别那么激动人心!只需更改一个位数!您在任何地方更改任何程序中的一个位数,输出都会更改。另外,也请阅读我的答案。起初我犯了一个错误,得到了-1,但后来对其进行了编辑,现在它包含了一个通用的解决方案problem@wormsparty:0.8
不能用单精度或双精度f精确表示loat。当转换为二进制时,0.8和0.9都是重复出现的。这两种情况的不同之处是什么?问题是0.8被放入一个浮点,因此它有一些二进制表示,可能是在接近0.8f的32位数字中。之后,比较是在一个双精度上进行的,因此为了比较,它将浮点数是一个双精度的64位表示,它不再精确地表示0.8,而是其他一些非常接近的数字。它将它与双精度0.8进行比较,双精度0.8没有受到转换的影响。查看下面的答案以了解更多细节。@Constantinius:是的,我同意你的解释ragarding提出的问题,但为什么不一样呢使用#include int main(){float a=0.9;如果(a@Nishant:因为对于0.9,(不准确的)单精度值恰好小于(不准确的)双精度值,而对于0.8则更大。
printf("a=%f\n", a);