什么?有被浮点数疑惑到;别急,我们一起来探讨一下~
首先来了解一下计算机的存储机制
1.整数,和数学概念一样,C语言中整数是没有小数部分的数的,计算机以二进制
存储整数
例如 7以二进制写是111
,要在8位字节中存储就要变为00000111
2.浮点数,C语言中整数加上小数就成了浮点数,比如7.00,同样计算机也是二进制
存储浮点数, 不过计算机却是把浮点数分为小数部分和指数部分分开存储,
(这里不理解也没关系)而书写浮点数的方法(e计数法)也做一下简单介绍
1e-10 = 1*10-10
1e10 = 1*1010
相比于整数,浮点数可以表示的范围更大,同时对于一些算术运算(如:两个很大的数相加减)浮点数损失的精度更多
接下来正文来了
因为在任何区间内都存在无穷个实数,所以计算机的浮点数不能表示区间内的所有值,浮点数通常只能是实际值无限接近的近似值,总之一句话就是“浮点数有误差
”C语言中无法做到精确,
我们这样写下一段代码:
#include<stdio.h> int main() { printf("%.17f", 0.1+0.2); return 0; }
却发现发现这段代码的输出结果并非0.300000...00000
而是0.30000...00004
,嗯哼?
大家都是知道1/10(0.1)这个数在十进制中当然没有任何问题,但是在二进制却没有这样的表示,1/10被写作为了
0.000110011001100110011
.....这样.无限循环下去
我们平常使用的32位浮点数只有23个有效数字,也就是说在23为以后我们的循环小数就被截断了,也就照成了精度损失。实际上我们的计算机存储的0.1已经非常接近了
但却不完全相等
输入值 0.1
实际存储 0.100000001490116119384765625...
再来看一个经典的例子
1/3 + 1/3 + 1/3 = 1
但是
0.33333+0.33333+0.33333却不等于1
OK
到这里已经差不到了,那么判断浮点数使用
0.3 + 0.4 == 0.7
显然是非常不可靠的
正确的做法是去计算这两个数的差别是否小于某个误差范围
如:
a = 0.3 + 0.4
b = 0.7
fabs(a-b)<1e-6 (,某个误差范围)