点击蓝字
关注我们
来源于网络,侵删一、引例
看下下面这段代码,会输出什么结果呢?
double x = 0;for (int i = 0; i < 10; ++i) {x += 0.1;}printf("%d\n", x == 1);
输出如下:
0
引起这种反差的原因就是浮点误差,浮点数在存储的时候是有精度误差的,所以进行浮点数等于判定的时候不能用 ‘==’,那么接下来我们看下浮点数的表示;
二、浮点数表示
1、IEEE 754
IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零 -0)与反常值),一些特殊数值(无穷(Inf)与非数值(NaN)),以及这些数值的“浮点数运算符”。
基于这个规定,任何浮点数都可以表示成如下形式:
2、单精度和双精度
C++ 中两种浮点数,float 和 double,分别代表单精度和双精度;
单精度尾数占23个比特位,指数占8个比特位;双精度尾数占52个比特位,指数占11个比特位;
由于结构相同,这里只介绍单精度浮点数;
3、单精度浮点数表示法
如图为 32位 的浮点数的二进制表示,总共 32 个比特位(取值 0 或 1);
S 在最高位,代表符号,负数为1,正数为0;
E 为从高到低的第 30 - 23 位,总共 8 位,代表指数偏移,存储的是加上了 127 以后的值(原因是指数有可能是负数);
F 代表二进制科学计数法的尾数,总共 23 位,因为是科学计数法,所以开头一定是 “1.” 开头,所以尾数有效位数为 24 位;
4、举例说明
【示例】 对于−18.375这个浮点数,求出它的二进制存储格式;
5、代码测试
C/C++ 中可以用如下代码对浮点数取地址转换成整型后输出整数的二进制表示;
float a = -18.375;unsigned int v = *((unsigned int *)&a);
三、浮点数判定
1、精度定义
#define eps 1e-6
2、相等判定
介于浮点数的表示方式,不能用 ‘==’ 进行相等判定,必须将两数相减,取绝对值以后,根据结果是否小于某个精度来判定两者是否相等;
bool EQ(double a, double b) { // EQualreturn fabs(a - b) < eps;
}
3、不相等判定
‘不相等’ 就是 ‘相等’ 的 ‘非’(取反);
bool NEQ(double a, double b) { // NotEQualreturn !EQ(a, b);
}
4、大于等于判定
‘大于等于’ 就是 ‘大于 或 等于’ 的意思,需要拆分成如下形式:
bool GET(double a, double b) { // GreaterEqualThanreturn a > b || EQ(a, b);
}
5、小于等于判定
‘小于等于’ 就是 ‘小于 或 等于’ 的意思,需要拆分成如下形式:
bool SET(double a, double b) { // SmallerEqualThanreturn a < b || EQ(a, b);
}
6、小于判定
‘小于’ 就是 ‘大于等于’ 的 ‘非’,需要拆分成如下形式:
注意:千万不能直接用 a < b
bool ST(double a, double b) { // SmallerThanreturn a < b && NEQ(a, b);
}
7、大于判定
‘大于’ 就是 ‘小于等于’ 的 ‘非’,需要拆分成如下形式:
注意:千万不能直接用 a > b
bool GT(double a, double b) { // GreaterThanreturn a > b && NEQ(a, b);
}
如果你年满18周岁以上,又觉得学【C语言】太难?想尝试其他编程语言,那么我推荐你学Python,现有价值499元Python零基础课程限时免费领取,限10个名额!
▲扫描二维码-免费领取
戳“阅读原文”我们一起进步