Skip to content

二的补码和浮点数表示

原码,反码和补码

在诸多可以表示有符号数字(带正负号的数字)时,人们发现 2's complement (二的补码) 是最佳的方式。因为他:

  1. 利用率最高,有多少种二进制组合,二的补码就能表示多少种数字

  2. 使得在计算机上使用与加法​​相同的电路进行减法运算变得非常简单

原理... who cares? 直接上干货

当一共有 n 位二进制数字时...

Signed magnitude (原码):

  • 原理:二进制数字的 MSB(最左边那位)被用来表示正负号,0=正,1=负
  • 最小可表示: (2n11)
  • 最大可表示: 2n11
  • 共可表示 2n1 种数字

1's complement (反码):

  • 原理:把每位颠倒,1变0,0变1
  • 最小可表示: (2n11)
  • 最大可表示: 2n11
  • 共可表示 2n1 种数字

2's complement (补码):

  • 原理:先把每位颠倒(做反码),再给结果加上 1
  • 最小可表示: 2n1
  • 最大可表示: 2n11
  • 共可表示 2n 种数字

浮点数表示

在人们吃饱了以后,又开始思考如何使用二进制表示浮点数。

可惜的是,不像二的补码,这回没有捷径可以钻了。人们只能定义一系列标准去约束这些表示法(例如,第几位表示什么,第几位到第几位表示什么...)

IEEE 754 是目前全世界最通用的浮点数表示法

你知道吗?

如果你正在学习 COMPSCI 101,你可以试试打开 Python,输入:

python
0.1 + 0.2

你会发现结果是 0.30000000000000004 。而且 0.1+0.2 == 3 的结果是 False

这就是拜 IEEE 754 标准所赐。更具体地说,这是因为十进制下的有限小数可能在二进制中只能用无限不循环小数来表示,因此造成了这样的结果。

不过,这个太高深了,我们不学。相反我们有一套国产自研的表示法:

0111111111011111
数字正负数字本身,丢掉小数点的二进制表示 (9位)指数正负指数大小 (5位)