双数的表示

Representation of double numbers

在8位表示中,我们知道数字4存储为00000100,数字-4存储为11111100。但是数字4.6如何存储在double中?

注意:问题可能更具体,您是否想知道特定编程语言或系统使用什么格式来表示双精度数。这将帮助我缩小答案范围并丢弃不相关的部分。

话虽如此,这是我的答案:

您描述的表示 4 和 -4 的格式称为二进制补码。它允许最高位表示符号,这意味着负数和正数可以由构成数字表示的位来表示。

浮点数通常以 IEEE-754 格式存储,这是一种独立于整数和其他“整数”数字的格式。

该格式基本上将二进制表示分为三个部分:符号、指数和分数。

符号是一个位,代表正(0)或负(1)。其他两个大小不同,但如果您熟悉该系统,它与科学记数法非常相似。

假设我们决定使用 32 位来表示小数。保留一位作为符号,所以我们有 31 位来存储数字的实际值。

0 00000000 00000000000000000000000 Sign Exponent Fraction

对于指数,我们希望正指数和负指数都代表非常大和非常小的数字。 IEEE-754 标准本可以使用您描述的熟悉系统来存储这些指数,但他们选择了不同的系统。相反,我们确定了一个 bias,它是 2(指数段中的位数 - 1)-1。如果我们在我的示例中使用 8 位作为指数段,则偏差为 27-1 或 127.

全1和全0的指数都是保留的。因此,我们可以用这个系统表示的最高和最低指数分别是 -126 和 127。

假设您要表示 1.4^2。 2 是你的指数。
我们的偏差是 127,所以您将指数存储为 2+127,即 129。

现在是分数。数字的小数部分必须严格大于或等于 0 且小于 1。坚持我在这里,但考虑十进制数及其工作原理。

1.2 = 1 + 2/10 = 1*100 + 2*10-1
0.0147 = 0/10 + 1/100 + 4/1000 + 7/10000 = 0*10-1 + 1*10-2 + 4*10-3 + 7*10-4

这里的趋势是十进制数可以分解为它的数字乘以用于编写它的数字系统的基数的连续幂(当你离开 . 时)。

现在考虑这个数字:
0.01101
它以一种称为 "binary fraction" 的表示形式编写。与之前的方法大致相同,这个数字可以写成一个总和,其中分母是 2 的连续更高次幂,即基数,随着我们远离该点:

0.01101 = 0/2 + 1/4 + 1/8 + 0/16 + 1/32 = 0*2-1 + 1*2-2 + 1*2-3 + 0*2-4 + 1*2- 5

既然我已经描述了二进制小数点的工作原理,让我们在浮点数的表示中使用它们。

表示的小数部分将是您希望表示的任何值,作为二进制分数,移入范围 [0,1]。

示例:
34.25 (= 3*101 + 4*100 + 2*10-1 + 5 *10-2 = 3 * 10 + 4 * 1 + 2 / 10 + 5 / 100 = 137/4)
转换为二进制小数点:
100010.01 (= 1 * 25 + 0 * 24 + 0*23 + 0* 22 + 1*21 + 0*20 + 0*2-1 + 1*2-2 = 32 + 4 + 1/4 = 137/4)
移动到范围 [0,1]:
1.0001001 * 25
这是将以我们的浮点格式存储的数字。

符号:0(正)
指数:5 + 偏差,127 = 132 = 10000100
分数:1.0001001 - 1 = .0001001(删除点,添加尾随零以填充段)= 00010010000000000000000

所以我们对 34.25 的完整浮点表示如下:
0 10000100 00010010000000000000000
无间距:
01000010000010010000000000000000

所以要提取我们的值,请执行以下操作:
(-1)sign * (1+fraction) * 2exponent - bias

这种表示的一个好处是无穷大和 NaN(“非数字”)之类的东西也可以通过那些保留的指数来表示。

您可以通过查看 IEEE-754 标准找到更多详细信息。

实际情况是,您可以按照自己喜欢的方式存储它,因为这些位只代表您决定让它们对您的程序意味着什么。但存储它们的标准方式是 IEEE-754 标准。

标准表示的缺点包括:
1. 有损表示
2.算术不准确
3. 用符号位将可表示的指数范围有效地分成两半,其他类型通过有符号和无符号版本来避免这种情况)

因此并不总是需要使用标准二进制表示。