jyy56350895 发表于 2021-9-7 23:35

c语言 double判断相等问题

#include<stdio.h>
int main(){
      double a,b,c;
      
      a=2;
      b=(65*0.98-32*1.99)*100;
      c=65*98-32*199;
      
      printf("%lf %lf %lf\n",a,b,c);
      
      if(a==b){
                printf("yes\n");
      }
      else{
                printf("no\n");
      }
      
      if(a==c){
                printf("yes");
      }
      else{
                printf("no");
      }
      return 0;
}

结果
2.000000 2.000000 2.000000    //a,b,c的值,显示都是相等的
no       //但是a就不等于b
yes   //a和c就相等

刚学,我知道因为double不能表达0,所以可能出问题。但是我搞不明白,为什么b这个公式算出来就不行,c就可以。
想问问具体是不能使用哪些情况。
在使用double时,所有的情况都应该用“<0.00001>0.00001”去判断吗??

花生土豆 发表于 2021-9-8 01:20

本帖最后由 花生土豆 于 2021-9-8 01:38 编辑

我水平有限,按我的理解回复一下吧,浮点数有符号,阶码(Exponent)和尾数(Mantissa)来表示一个数;那里的一套方法,我说不清;
这里显示的数字2.0000,在编码上是可能不同的,所以我这里就是把这个a,b,c地址的值直接给用十六进制表示一下(用int来强转是因为int的字节数和它的表示方法比浮点简单),就能区分出编码的不同;



printf("%x %x %x\n",(int)(*(&a)),(int)(*(&b)),(int)(*(&c)));

显示结果是:2,1,2 你看一下了,供参考;

DrCatcher 发表于 2021-9-8 07:39

浮点数,带小数的有精度损失

愚者—我 发表于 2021-9-8 07:44

浮点数的精度损失是比整数多的,毕竟底层是将指数和小数部分分开存储

answdl 发表于 2021-9-8 08:06

在监视窗口看0.98和1.99分别存储为
        0.97999999999999998        double
        1.9900000000000000        double
double类型数据大小相等判断,要根据两值之差的绝对值小于等于10的-16次方
float                         4 字节          6 位有效位
double                 8 字节          15 位有效位
long double       16 字节          19 位有效位

一剑飘零 发表于 2021-9-8 08:12

精度不够。我也遇到过。

agd 发表于 2021-9-8 08:18

用%.16lf,多打印几个小数,就能看出区别了。

愚者—我 发表于 2021-9-8 09:10

计算机是缺少足够的小数位来进行我们的浮点数的计算, 例如我们有一个float num = 3e20, 那进行+或乘的时候, 就需要更高位的空间来进行处理,但是如果是float num = 3e2; 那么在处理的时候就不会出现问题了, 因为不会出现舍入错误。
具体的信息你可以看下一c priemr plus,我记得在它的前面有讲解

阳光肥肥 发表于 2021-9-8 09:19

由于浮点数的存储方式 他不是精确的 一般来说进行比较的时候只要 (a-b)<某个范围 就认为a和b相等

ongp1347 发表于 2021-9-8 10:58

花生土豆 发表于 2021-9-8 01:20
我水平有限,按我的理解回复一下吧,浮点数有符号,阶码(Exponent)和尾数(Mantissa)来表示一个数;那里的 ...

这位同学很优秀 用整数查看小数在机内表示是一种惯用方法 这就是小数无法用 ==、!= 来比较的原因 只能 x - 0.000000000000001 < y && y < x + 0.000000000000001 表示相等
页: [1] 2
查看完整版本: c语言 double判断相等问题