先说说32 位的 float型
一个正的浮点数 X, 在计算机中表示为:
X = a * 2e
这里 e 代表指数, a 代表尾数, 在 计算机内部, 他们都是用二进制表示的. 其中 a 用二进制的科学表示法表示, 由于科学表示法第一位总是1 (0除外) , 所以第一位略去不计. e 表示的时候, 因为要表示出负数, 所以 e要加上127 , 实际运算的时候要减去127.
IEEE 规定, 32 位 float型被拆开成以下格式, 左边为高位:
二进制 |
0 |
0000 0000 |
000 0000 0000 0000 0000 0000 |
位数 |
共1位 |
共8位 |
共23位 |
含义 |
符号位 |
指数位 |
尾数位 |
范围 |
0正1负 |
-127到+127 |
0到0x . 7f ff ff |
float 的范围是 -3.40282 * e38 ~ + 3.40282 * e38
一般在人看来是 十进制的数, 要转换成二进制. 十进制转二进制, 大于1 的部分就是除以2 取余;小于1 的部分乘2 取整.
比如 8.5 转换成二进制就是 1000.1 , 处理成这一步, 还要用科学表示法表示, 就成了 1.0001 * 23 , 注意: 由于1.0001 第一个1 要去掉, 所以成了 0001 , 3 需要加上 127 就成了 130 , 二进制就是 10000010。则套用上面话就表示为:
0 10000010 0001 000 0000 0000 0000 0000
16 进制 就是: 0x 41 08 00 00 , 一般来说 , intel 系列的 CPU 都使用的是 小尾存放, 就是 高字节放在后面, 刚好要掉过来就是: 0x 00 00 08 41 , 这样就完成了一次浮点数的表示.
注意: 浮点数 0.0 在计算机中表示为 0x 00 00 00 00 .
那么浮点数的精度是怎么回事情呢? 当我们使用二进制表示 大于1 的部分的时候, 没有问题, 除以2,一直下去, 最后一位肯定不是1 就是 0; 那么小数部分呢? 举个例子, 比如 0.8
表示 0.8
* 2
1.6 - 1 = 0.6
* 2
1.2 -1 = 0.2 - 0
.* 2
0.4 - 0
*2
0.8 - 0
这样就循环了 就是说 0.8 的二进制 就是 0.11000 11000 ...... 一直循环下去, 而我们计算机如果表示0.8只能取0后面的前几十位, 这就说明 如果是 0.800....001 (循环超过100次) , 它表示出来的值其实是和 0.8 一样, 所以我们比较float型的数字 用 a == b 其实是不严谨的(精度问题), 一般都是 用 abs(a - b) < 0.000001 之类就默认是相等.
那么 double型呢? 咱们可以照 float 型的葫芦 来画了.
double 型 只是说 取 64 位, 比float型的位 多一倍
IEEE 规定 double 型 ,
第64位 63-54 53-1
符号位 指数位 ( -1024 - 1024) 尾数位
所以 double型的范围是 -1.79769 * e308 ~ +1.79769 * e308
多用了几位, 表示范围大了很多, 其实本质跟float型一样.