Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 浮点比较给出了不同的结果_C++_C_Floating Point - Fatal编程技术网

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);