浮点数的二进制表示

541 阅读3分钟

我们以32位的单精度为例:

(1)s×1.f×2e(-1)^s×1.f×2^e

单精度的32个比特可以分成三部分。

第一部分是一个符号位符号位,用来表示是正数还是负数。我们一般用s来表示。在浮点数里,我们不像正数分符号数还是无符号数,所有的浮点数都是有符号的。

接下来是一个8个比特组成的指数位指数位。我们一般用e来表示。8个比特能够表示的整数空间,就是0~255。我们在这里用1~254映射到-126~127这254个有正有负的数上。因为我们的浮点数,不仅仅想要表示很大的数,还希望能够表示很小的数,所以指数位也会有负数。

你发现没,我们没有用到0和255。没错,这里的 0(也就是8个比特全部为0) 和 255 (也就是8个比特全部为1)另有它用,我们等一下再讲。

最后,是一个23个比特组成的有效数位。我们用f来表示。综合科学计数法,我们的浮点数就可以表示成下面这样:

(1)s×1.f×2e(-1)^s×1.f×2^e

你会发现,这里的浮点数,没有办法表示0。的确,要表示0和一些特殊的数,我们就要用上在e里面留下的0和255这两个表示,这两个表示其实是两个标记位。在e为0且f为0的时候,我们就把这个浮点数认为是0。至于其它的e是0或者255的特殊情况,你可以看下面这个表格,分别可以表示出无穷大、无穷小、NAN以及一个特殊的不规范数。

根据浮点数的二进制表示求出10进制

先看这个公式(1)s×1.f×2e(-1)^s×1.f×2^e, 之前很长一段时间都没有正确理解这个公式, 导致没有搞清楚浮点数.

很重要的的一点, 这是一个二进制的公式, 此前我一致用10进制的思路来看待它, 怎么算结果都不对.

我以一个例子来说明, 9.1的二进制表示如下:

1001.00011001100110011001

用上面的公式可以表示成:

$1×1.00100011001100110011001×2^3$
0 00000011 00100011001100110011001
s e        f  

这时千万不要用10进制的思维来看待, 比如1.0010 001100110011001 * 8 = 8.00800088... , ×23×2^3 指的是小数点向右移动3位, 参考10进制中5.555×1035.555×10^3表示是将5.555的小数点向右移动3位.

移动之后变成了1001.000110011001100110011001.00011001100110011001, 这是二进制表示的一个实数, 有整数部分, 也有小数部分;

如何转换成10进制? 1001.000110011001100110011001.00011001100110011001有点长, 我换个短一点的二进制表示的实数10.10110.101, 看是如何转成10进制的.

1×21+0×20+1×21+0×22+1×23=2.6251×2^1 + 0×2^0 + 1×2^{-1} + 0×2^{-2} + 1×2^{-3} = 2.625

整数部分: 1×21+0×20=21×2^1 + 0×2^0 = 2

小数部分: 1×21+1×23=0.6251×2^{-1} + 1×2^{-3} = 0.625

正如10进制中, 小数后的位代表的是0.1、0.01、0.001...

10进制中, 小数后的位代表的是0.5、0.25、0.125...

求一个浮点数的二进制表示步骤

  1. 转化成二进制实数

我们以2.75为例:

2.75 --> 10.11

整数部分: 1×21+0×20=21×2^1 + 0×2^0 = 2 小数部分: 1×21+0×22=0.751×2^{-1} + 0×2^{-2} = 0.75

  1. 将二进制实数用标准公式表示,得到s,e,f

10.11 --> 1×1.011×211×1.011×2^1

s: 1 e: 1 f: 011

1 00000001 00000000000000000000011
s e        f  

至于十进制的浮点数怎么表示成二进制请看深入理解浮点数到底有什么用?