王鹏飞

Blog

Tutorial

About

开发者笔记

2021年11月29日

计算机是如何存储数字的—IEEE754

多年以前在大学学习C++时,知道了IEEE 754是目前计算机最普遍的数字表示方式。但是由于工作上与之打交道甚少,经常忘记这一标准的具体细节,所以我写了这篇文章详细记录下来。

如何表示数字?

表示数字有很多种方式。例如,我们书写时最常用的方式——固定小数点位置,在几个数字中间放置一个小数点表示小数,如果没有小数点就表示整数。

还有一种方式,是科学计数法,它由基数部分和指数部分组成。例如用科学计数法表示十进制整数50

5 x (10 ^ 1)
0.5 x (10 ^ 2)
0.05 x (10 ^ 3)

...

123.45可以表示成如下几种方式。

0.12345 x (10 ^ 3)
1.2345 x (10 ^ 2)
12.345 x (10 ^ 1)
123.45 x (10 ^ 0)
1234.5 x (10 ^ -1)

...

其中5 x (10 ^ 1)1.2345 x (10 ^ 2)被称作标准科学计数法,其中左侧数字部分的小数点左侧只有一位非0数字。

如果用标准科学计数法表示,表示二进制数字,则指数的底数为2。

二进制10100.110表示为1.0100110 × (2 ^ 4)

IEEE 754本质上就是二进制的标准科学计数法。

IEEE 754

首先看一下IEEE 754的存储结构。

符号(Sign) 指数(Exponent) 尾数(Fraction)
单精度(Single Precision) 1 [31] 8 [30-23] 23 [22-00]
双精度(Double Precision) 1 [63] 11 [62-52] 52 [51-00]

C++中单精度浮点数,用4个字节表示,一个字节等于8bit,所以总共有32bit。最左侧一位用来存储符号位,23-30位存储科学计数法的指数部分,0-23位存储科学计数法的非指数部分,这里叫做尾数部分。双精度用8个字节表示,最左侧位为符号位,52-62表示指数部分,0-51表示尾数部分。

假设符号位为正,指数部分存储的是70,尾数部分是1.1001(二进制),则表示的数值为1.1001 x (2 ^ 70)

下面依次解释符号、指数和尾数三个部分。

符号

IEEE 754的符号位用来表示正数和负数,符号位为0表示正数,1表示负数,it's so easy。

指数

单精度结构下,IEEE 754的指数部分有8位,8位可以表示的最大整数为255(2 ^ 8 - 1),因为指数部分既要表示正数,也要表示负数,所以需要有一个偏移值,对于单精度这个偏移值为127,所以指数部分存储的是200,表示的是(200 - 127),0表示(0 - 127),即-127。

双精度结构下,IEEE 754的指数部分有11位,此时计算偏移值为1023,所以0表示-1023。

尾数

采用标准的二进制科学计数法,那么尾数部分小数点前肯定是1(二进制只可能是1和0,因为是标准科学计数法,所以是1)。既然确定了小数点前是1,那么不需要再用单独的1个bit表示,所以尾数部分所有bit用来表示小数点右侧的数值。例如存储了100111,那么结果是1.100111,所以32位浮点数的Fraction有32位,但是它表示了24位数值加一个小数点。

以上,就是通过IEEE 754表示浮点数的过程,如果理解了IEEE 754,很容易能计算出单精度和双精度所能表示的数值范围。

(完)

留言(0


发表评论

邮箱地址不会被公开。*表示必填项