第一篇博文,准备记录一下C/C++中一些容易踩到坑(那种难搜到的问题,请教别人才弄明白的)。欢迎指正写得不对的地方,本文会持续更新。
浮点数不能直接用==判等
如果想要判断两个浮点数是否相等,直接在if中使用==判断有时会得到错误的结果,比如下例会输出”nope…”
其原因是,浮点数在计算机里表示的形式不像整形那样简单。
float单精度浮点数在计算机里面表示形式由3部分组成符号位(1位),指数位(8位),尾数部分(23位)。
对于浮点数120.5,用科学记数法表示为1.205*10^2
转换成二进制,1.20510^2 = 1.11011012^6
我们把上面的二进制表达式,看成n*2^m,对应到上面的3个部分就是
符号位,正数为1,负数为0;
指数位,存放表达式中的m值,根据IEEE754规范的规定,m实际存储时,需要加上一个固定值127;
尾数位,存放表达式中的n值,因为n的首位一定是1,n实际存储时,会把第一个1省略掉,所以实际尾数位可以表达24位的内容;
所以,在内存中120.5的二进制表达方式应该是这样的:
符号位是1
指数位,m是6,加上127等于133,所以指数位是10000101
尾数位,n是1.1101101,去掉第一个1,那么尾数为是1101101,后面空着的位都补0。
所以120.5在内存中的表示是0100001011101101000000000000。
回到最初的问题,浮点数使用==判断相等时,程序会直接拿内存储存的内容按位比较。可以看到
这样的表示方式,节省了非常多的空间,但是代价是引入了误差(当尾数位超过24位时)。
所以,浮点数判断相等的正确做法是,将两个数相减之后取绝对值,然后判断这个绝对值是否小于某个值。比如:
至此,问题基本解决。
感谢某不愿透露姓名的+7学弟,还有1e-7这种高端写法也是这位某学弟教我的- -