向下舍入浮点数

Rounding down float

提问人:kvkemroo 提问时间:3/1/2018 最后编辑:kvkemroo 更新时间:3/2/2018 访问量:165

问:

首先,让我给出 32 位浮点和十进制表示的十六进制和二进制。

0x5060000f = 01010000011000000000000000001111 = 15032400896
0x43800005 = 01000011100000000000000000000101 = 256.000152587890625

我的老师说添加 1 次和 24 次浮点数在最后 3 位有四舍五入误差。0x5060000f0x43800005

她是什么意思?

15032400896 + 24 * 256.000152587890625 =
15032407040.003662109375 =
01010000011000000000000000010101 =
0x50600015
浮点精度

评论

1赞 Alexander Elgin 3/1/2018
你应该问问老师,她的解释中是否有你不清楚的地方
0赞 Dijkgraaf 3/2/2018
浮点数学是否损坏的可能重复?

答:

2赞 Eric Postpischil 3/1/2018 #1

首先,让我们看一下编码数字的部分,我将标记 (15032400896) 和 (256.000152587890625):ab

a: 0 10100000 11000000000000000001111
b: 0 10000111 00000000000000000000101

两个符号位均为 0,表示数字为正数。的指数字段是 10100000,即 160。编码指数偏置 127,因此实际指数为 160−127 = 33。(我假设使用 IEEE 754 基本 32 位二进制格式。的指数域是 10000111,即 135,因此它的实际指数是 8。ab

它们在浮点的正常范围内(因为编码的指数不为零。当指数为零时,该数字为次正态值。在正常范围内,有一个隐式的“1.”作为有效前缀。(有效部分是数字的小数部分。有时它被称为“尾数”,但这是纸质对数表时代的遗留术语。“Significand”是首选术语。

第一个数字的有效性字段是 11000000000000000001111,因此实际有效性是 1.1100000000000000000001111(作为二进制数字)。第二个数字的有效字段为 00000000000000000000101,因此其实际有效为 1.0000000000000000000001。

现在我们已经完全解码了这些数字,可以看到它们的数学值是:

a = 1.11000000000000000001111 • 233
b = 1.00000000000000000000101 • 28

问题是当计算 和 的总和时会发生什么,所以首先我们需要找到 .由于 24 是一个简单的数字,我将跳过显示其完整的浮点表示形式,而只是乘以 24。我们可以简单地将其有效数乘以 24 来做到这一点,从而得出:a24*b24*bb

24*b = 11000.0000000000000000111 1 • 28

我用粗体标记了前 24 位,并在它们和其余位之间留了一个空格。这是因为浮点格式在有效数中只有 24 位。因此,计算机必须将精确的数学结果四舍五入以适合 24 位。我们可以向下舍入到 11000.000000000000000000111,或者向上舍入到 11000.0000000000000000001000。由于剩余的位在它们之间是等距的,因此我们有一个平局。浮点运算中最常用的舍入规则是四舍五入到最接近的表示值,如果出现平局,则四舍五入到偶数。因此,我们四舍五入,结果是:

24*b → 11000.0000000000000001000 • 28

接下来,我们要对表示进行归一化,使有效数以“1.”而不是“11000”开头。为此,我们调整指数:

24*b → 1.10000000000000000001000 • 212

我将这个结果称为 .现在我们要添加 和 ,它们是:cac

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 位浮点计算的最终结果。四舍五入已经发生,但我不明白如何将其描述为“最后 3 位的四舍五入错误”。如果结果是用精确的数学计算得出的,它将是:a + 24*b

1.110000000000000000101010000000000000000001111000 • 233

因此,我们可以看到计算结果的最后一位是正确的,并且发生的舍入误差在值上要低得多。

评论

0赞 aka.nice 3/2/2018
Multiplying by 24 (3*8 =multiply by 3 and shift the exponent by 3) would require a 25 bit significand since the LSB is 1... <pre>1.100000000000000000001111 • 2<sup>12</sup></pre> The first 2 bits are above the LSB of the big number which is <pre>2<sup>10</sup></pre> and will be accounted for in the result. But the 3 last trailing bits of the original smallest number are way too far. That's as if they were truncated before the operation (but I don't like to see it that way, I prefer the view of Eric)
0赞 Eric Postpischil 3/2/2018
When I first saw the question, it was not clear to me what OP meant. But now I think they may have been referring to adding to , where and are the two numbers. I am planning to update the answer showing that addition when I have some time.1*a24*bab