首先让我给出32位浮点和十进制表示的十六进制和二进制。
0x5060000f = 01010000011000000000000000001111 = 15032400896
0x43800005 = 01000011100000000000000000000101 = 256.000152587890625
我的老师说,在最后 3 位中添加1次0x5060000f
和24次0x43800005
浮点数会出现向下舍入错误。
她是什么意思?
15032400896 + 24 * 256.000152587890625 =
15032407040.003662109375 =
01010000011000000000000000010101 =
0x50600015
答案 0 :(得分:2)
首先,让我们看一下编码数字的部分,我将标记为a
(15032400896)和b
(256.000152587890625):
a: 0 10100000 11000000000000000001111 b: 0 10000111 00000000000000000000101
两个符号位均为0,表示数字为正数。 a
的指数字段为10100000,即160.编码指数偏向127,因此实际指数为160-127 = 33.(我假设使用IEEE 754基本32位二进制格式。 )b
的指数字段为10000111,为135,因此其实际指数为8.
这些在浮点的正常范围内(因为编码的指数不为零。当指数为零时,数字是次正规的。)在正常范围内,有一个隐含的“1”前缀尾数。 (有效数是数字的一小部分。有时它被称为“尾数”,但这是从对数纸张表日起的遗留术语。“重要”是首选术语。)
第一个数字的有效数字字段是11000000000000000001111,因此实际有效数字是1.11000000000000000001111(作为二进制数字)。第二个数字的有效数字字段为00000000000000000000101,因此其实际有效数为1.00000000000000000000101。
现在我们已完全解码数字,可以看到他们的数学值是:
a = 1.11000000000000000001111 • 233 b = 1.00000000000000000000101 • 28
问题是当计算a
和24*b
的总和时会发生什么,所以首先我们需要找到24*b
。由于24是一个简单的数字,我将跳过显示其完整的浮点表示,并简单地将b
乘以24.我们可以通过将其有效数乘以24来做到这一点,这会产生:
24*b = 11000.0000000000000000111 1 • 28
我用粗体标记了前24位,并在它们和剩下的位之间留了一个空格。这是因为浮点格式在有效数中只有24位。因此,计算机必须将精确的数学结果舍入到24位。我们可以向下舍入到11000.0000000000000000111,或向上,到11000.0000000000000001000。由于剩下的比特在这些之间是等距的,我们有一个平局。浮点中使用的最常见的舍入规则是舍入到最接近的表示值,如果是平局,则舍入到偶数位。所以我们四舍五入,结果是:
24*b → 11000.0000000000000001000 • 28
接下来,我们要对表示进行规范化,使有效数字以“1”而不是“11000”开头。为此,我们调整指数:
24*b → 1.10000000000000000001000 • 212
我会将此结果称为c
。现在我们要添加a
和c
,它们是:
a = 1.11000000000000000001111 • 233 c = 1.10000000000000000001000 • 212
当处理器添加数字时,它会有效地移动有效位数以对齐表示相同幅度的位。对齐这些数字会产生:
1.11000000000000000001111000000000000000000000 • 233 0.00000000000000000000110000000000000000001000 • 233
然后我们可以添加数字,产生:
1.11000000000000000010101000000000000000001000 • 233
使用粗体和空格标记前24位显示:
1.11000000000000000010101 000000000000000001000 • 233
这次,剩下的比特低于中点,所以我们向下舍入,结果是:
1.11000000000000000010101 • 233
这显示了在32位浮点中计算a + 24*b
的最终结果。舍入已经发生,但我没有看到它如何被描述为“最后3位的舍入错误。”如果结果是用精确的数学计算的,那就是:
1.110000000000000000101010000000000000000001111000 • 233
因此,我们可以看到计算结果在其最后位中是正确的,并且已经发生的舍入误差的值相当大。