参考资料:
1. 浮点数进制转换, Mr.Rico个人博客
2. 浮点存储和取值范围,CSDN treasurew 博客
3.【学习记录】正数乘以正数等于负数?| 整数和浮点数在计算机中的存储,B站Up 笨手笨脚oO
符号位 | 指数位 | 有效数字位 |
|---|---|---|
表达这个数字的正负,二进制1表示负,0表示正 | 存放规范化指数形式的指数位 | 存放有效数字 |
32位二进制(4个字节)
符号位 | 指数位 | 有效数字位 |
|---|---|---|
1bit | 8bit | 23bit |
64位二进制(8字节)
符号位 | 指数位 | 有效数字位 |
|---|---|---|
1bit | 11bit | 52bit |
别问为什么是这样的!
问就是规定!!!
十进制小数转二进制
方法:乘二取整,顺序排列,加上小数点。
案例:
十进制的0.8125转换成二进制:

图片来源:参考资料1:浮点数进制转换, Mr.Rico个人博客
十进制的10.8125转换成二进制:
整数位和小数位分开转换,整数位简单,小数位同上,再用小数点连接。
10转换成二进制为01010
所以10.8125转换成二进制为: 01010.1101
番外:小数二进制转换成十进制
方法: 加权系数展开
图片来源:参考资料1:浮点数进制转换, Mr.Rico个人博客
所以本例中的 100.1 转化成二进制为:
整数位:100 —— 二进制:01100100
小数位:0.1 —— 二进制:0.000110011001100…
最终结果:01100100.0001 1001 1001 1001…
还是上边的这个数100.1
转化为二进制表达的标准化指数形式:小数点向左移动6位
最终结果约为:1.100100 e-6
PS:
① 十进制也可以先转换成以2为底数的标准化指数形式,再转换成二进制。
② 十进制先转化二进制,再转化成标准指数化形式,直接移动位数就行。(为啥是这样的?以我们熟悉的十进制为例: 3.89*10^4,就是小数点向右移动4位,38900)
32位二进制(4个字节)
符号位 | 指数位 | 有效数字位 |
|---|---|---|
1bit | 8bit | 23bit |
① 100.1是正数,所以第一位是0
1.100100 e-6
② 左移6位,表达成e-6,这个指数位存的就是-6;在8位二进制条件下存储。指数是以阶码的形式存储的。
两种方式看他是怎么存储的:
第一种:
① 先求移码:移码是补码的符号位取反,(-6)的补码是:1111 1010 所以移码结果应该是:0111 1010
④ 再求阶码(浮点数指数位存储形式): 阶码=阶数的移码-1 0111 1001
第二种:
这个指数位存储的二进制用十进制表示恰好是等于:偏置数(8位偏置127;11位偏置1023)+阶数
127+(-6)= 121
转换成二进制:0111 1001
可以看到第二种和第一种方法得出的结果一样
所以直接用第二种计算简单一点。
问题又来了???
偏置值是个什么鬼?
因为存指数位的那个数据是一个无符号的整数形式的数据,8位无符号的整数形式取值范围为:0~255;但是事实上,指数有负数的情况,例如这道题,指数就是-6.那该如何用一个无符号的整数表达负数呢?
干脆把0~255劈一半,0~127;-127~-1;那么只要把是负数的数字加上127就变成了一个无符号整数可以表达的形式了。
所以8位二进制指数偏置值为127;
64位二进制偏置值为1023
计算方法:[2^(位数)]/2-1
③ 有效数字位
1.1001 0000 01100……
由于最高位肯定是1,所以存储时可以把1甩掉,取出来的时候再补上。
所以存到计算机里的是:
1001 0000 0110 0110 0110 011(23位)
最终结果:
【0】【0111 1001】【1001 000 0110 0110 0110 011】
根据指数位在内存中存储的数字(e)的大小一共有4种情况 ,其中E表示实际阶数, Bias为偏置值(127或1023);M为小数部分存放的数字
图片来源参考资料3
$1 \le e\le 254$ | \(e=0\);\(M\ne0\) | \(e=255\);\(M=0\) | \(e=255\);M$\ne 0$ |
|---|---|---|---|
\(V=(-1)^s*1.M*2^{e-127}\) | \(V=(-1)^S*0.M*2^{-126}\) ,表示正负无穷0,以及接近0的很小的数字 | 表示无穷 | NAN |
根据这个规则,我们可以看到,它可以存放0;无穷;那么8位二进制所能表达的一般浮点数的范围是什么呢?
也就是当e取1~254之间的数
当e=254时,即二进制为:1111 1110 时;(当e全为1的情况时,即e=255,这时表示的是无穷或者不是一个数字),所以254是指数位表达一般浮点数字时所存放的最大的数字。
减去存放时加上的偏置值127,实际存放的最大阶数为 \(Emax=254-127=127\) ;
有效数字位M可以存放23位,最大即23位全为1时
加上被甩掉的1,所以最终结果以二进制表达为:1.1111……1111(小数点后23个1),再乘以阶数127,这个数字用二进制表达为: $1.1111……1111*2^{127}$
需要注意的是这是二进制的表达方式,阶数是几,就把小数点向右移动几位,所以这个直接把小数点向右移动127位,得到了以二进制表达的最大浮点数:1111111……11111(128个1)
换算成10进制为: $2^{128}-1\approx3.4e38$
这就是32位二进制所能表达的最大浮点数的由来。
下面分析最小的数,由于这种存储方式,有符号位,所以最小的数肯定是 -(3.4e38);
值得分析的是除去无穷接近于0的情况,所能表示的一般数字种绝对值最小的浮点数(0.000000???)是多少
指数位最小应该是e=1的情况,减去偏置值127,也就是-126;
而有效数字位最小就是全为0,
最终这个绝对值最小的浮点数以二进制表示为: $1.0*2^{-126}$
同理,这个是小数点向左移126位,得到:0.000……000(125个0)1 这是二进制表达的
换算成10进制为: $1*2^{-126}\approx1.2e-38$ (事实上是0.000……000(37个0)11754943……)
本文章使用limfx的vsocde插件快速发布