一、结论
1. 可以直接比较的场景
/*
* 两个double类型变量都是直接赋同样的值,可以直接比较,因为他们在内存中存储的二进制码相同。
*/
int main(){
double a = 0.01;
double b = 0.01;
// 或者 double a = 0.01; double b = a;
if(a == b){
printf("a==b\n");
} else {
printf("a!=b\n");
}
}
2. 不可以直接比较的场景
/*
* 两个double类型变量的值是通过计算得到的,此时不可以直接比较,因为在内存中存储的二进制码不同,打印的值看着相同,是因为打印精度默认是6位,精度不够,使用%18lf或更高精度打印,就会发信打印值不同。
*/
int main(){
double a = 2.11;
double b = 2.10;
double c = a - b;
double d = 7.37;
double e = 7.36;
double f = d - e;
if(c == f){
printf("c == f\n");
} else {
printf(" c != f\n");
}
return 0;
}
二、原理
1. 浮点数在计算机中的表示方法
例:7.625的表示: 整数部分:7 -> 111 小数部分: 0.625 = 0.5 + 0.125 -> 0.101 // 2-1 = 0.5, 2-2 = 0.125,对应小数点后.1和.01,以此类推。 7.625 = 111.101 = 1.11101 * 2^2 这是理想状态下,浮点数可以被准确的表示,但是如果是浮点数7.626呢?它只能被近似表示,只是精度上可以调整。 7.626 = 7.625 + 0.001, 但是0.001并没有2n 或2n 的和可以表示,所以只能近似表示。如表示为 2-10 = 0.0009765625; 7.625 + 0.0625 + 2-10+2-14+… 正是因为这样的非准确表示方式,导致c = a - b, f = d - e; 因为a,b,d,e表示精确度的不同,导致c和e结果不同。
当然了,上述只是浮点数的二进制表示法,进一步存储到计算机中还要划分符号位,尾数部分,指数部分,这些部分的文章较多,就不展开了。
|