今天来说下小数在计算机中是怎样存储的。

定点数与浮点数

小数点在计算机中通常有两种表示方法:

  • 约定所有数值数据的小数点隐含在某一个固定位置上,称为定点表示法,简称 定点数
  • 小数点位置可以浮动,称为浮点表示法,简称 浮点数

1. 定点数表示法(fixed-point)

所谓定点格式,即约定机器中所有数据的小数点位置是固定不变的。在计算机中通常采用两种简单的约定:

  • 将小数点的位置固定在数据的最高位之前。
  • 将小数点的位置固定在最低位之后。

一般常称前者为 定点小数,后者为 定点整数

  • 定点小数是纯小数,约定的小数点位置在符号位之后、有效数值部分最高位之前。

若数据 x 的形式为 x = x0.x1x2…xn ( 其中x0为 符号位,x1~xn是数值的有效部分,也称为 尾数, x1为最高有效位 ),则在计算机中的表示形式为:

1
2
3
4
  |符号位 |小数点位置 |数值部分
  +------+----------+-------+-------+----------------+-----------+
  |  x0  |          |  x1   |  x2   |     .......    |    xn     |
  +------+----------+-------+-------+----------------+-----------+

一般说来,如果最末位 x^n = 1,前面各位都为 0 ,则数的绝对值最小,即 |x|min = 2^-n 。如果各位均为 1,则数的绝对值最大,即 |x|max =1-2^-n 。

所以定点小数的表示范围是:2^-n ≤ | x | ≤ 1 - 2^-n

  • 定点整数是纯整数,约定的小数点位置在有效数值部分最低位之后。

若数据 x 的形式为 x = x0 x1x2…xn ( 其中x0为 符号位,x1~xn 是 尾数, xn 为最低有效位 ),则在计算机中的表示形式为:

1
2
3
4
  |符号位 |数值部分                                  |小数点位置
  +------+------+------------------------+---------+-------------+
  |  x0  |  x1  |      ..........        |    xn   |             |
  +------+------+------------------------+---------+-------------+

定点整数的表示范围是:1≤ | x | ≤ 2^n - 1

当数据小于定点数能表示的最小值时,计算机将它们作0处理,称为 下溢;大于定点数能表示的最大值时,计算机将无法表示,称为 上溢,上溢和下溢统称 溢出

计算机采用定点数表示时,对于既有整数又有小数的原始数据,需要设定一个比例因子,数据按其缩小成定点小数或扩大成定点整数再参加运算,运算结果,根据比例因子,还原成实际数值。若比例因子选择不当,往往会使运算结果产生溢出或降低数据的有效精度。 用定点数进行运算处理的计算机被称为定点机。

2. 浮点数表示法(floating-point number)

与科学计数法相似,任意一个J进制数N,总可以写成N = J^E × M

式中M称为数 N 的尾数(mantissa),是一个纯小数;E 为数 N 的阶码(exponent),是一个整数,J称为比例因子 J^E 的底数。这种表示方法相当于数的小数点位置随比例因子的不同而在一定范围内可以自由浮动,所以称为浮点表示法。

底数是事先约定好的(常取2),在计算机中不出现。在机器中表示一个浮点数时,一是要给出尾数,用定点小数形式表示。 尾数部分给出有效数字的位数,因而决定了浮点数的表示精度。二是要给出阶码,用整数形式表示,阶码指明小数点在数据中的位置,因而决定了浮点数的表示范围。 浮点数也要有符号位。因此一个机器浮点数应当由阶码和尾数及其符号位组成:

1
2
3
4
|阶符   |阶码            |尾符   |尾数                            
+------+----------------+-------+------------------------------+ 
| Es   |     E          |  Ms   |           M                  | 
+------+----------------+-------+------------------------------+ 

当底数取 2 时,二进制数 N 的小数点每右移一位,阶码减小 1,相应尾数右移一位;反之,小数点每左移一位,阶码加 1,相应尾数左移一位。

若不对浮点数的表示作出明确规定,同一个浮点数的表示就不是唯一的。例如 11.01 也可以表示成 0.011012-3 ,0.1101×2-2 等等。 这个时候就需要一个统一的标准,现在比较通用的标准是IEEE 754:

float(32位单精度)

1
2
3
4
|符号位|指数位            |尾数位
+------+----------------+--------------------------------------+
|1bit  |     8bit       |               23bit                  |
+------+----------------+--------------------------------------+

double(64位双精度)

1
2
3
4
|符号位|指数位            |尾数位
+------+----------------+--------------------------------------+
|1bit  |     11bit      |               52bit                  |
+------+----------------+--------------------------------------+