如何减去两个正 IEEE-754 数?
How to subtract two positive IEEE-754 numbers?
所以我有点无奈。我想我了解如何对 IEEE-754 数字进行加法运算,但我在减法方面遇到了很大的问题。我感觉,我的想法是对的,但是我想跟大家验证一下。
所以我们有以下两个 IEEE-754 编号:
x: 0 1000 0010 100 1000 0000 0000 0000 0000
y: 0 1000 0011 010 1001 0000 0000 0000 0000
因为我们必须要正数并且我们想减去它们,我的想法是取 y,反转尾数并计算
x+(-y)
一位导师告诉我,那是不正确的,我必须保持数字为正,然后减去它们。他为什么不告诉我,怎么不告诉我。
谁能告诉我正确的方法是什么?
我对 x-y 方式的想法:
- 将指数从 x 扩展到 1000 0011
- 将 x 的尾数移动 1
- 以正常方式将两个数相减
所有产生正确结果的方法都是正确的。通过从较大的绝对值中减去较小的绝对值并相应地调整符号位,舍入可能更容易处理。同样,使用正数只会使处理 1<<23 处的(可选)隐式数字变得稍微容易一些。对于负值,数字需要为 0xff800000。对于负非正规化,也会出现其他特殊情况。
OP 的 1-2-3 想法大部分是正确的,但可能错过了隐含的部分。
1 考虑隐含位。
s eeee eeee mmm mmmm mmmm mmmm mmmm mmmm
x: 0 1000 0010 100 1000 0000 0000 0000 0000
y: 0 1000 0011 010 1001 0000 0000 0000 0000
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm
x: 0 1000 0010 1100 1000 0000 0000 0000 0000
y: 0 1000 0011 1010 1001 0000 0000 0000 0000
2 调整较小的数量级,形成一个公共指数。 (增量博览会,转移“尾数”)
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm extra bits
x: 0 1000 0011 110 0100 0000 0000 0000 0000 0
y: 0 1000 0011 1010 1001 0000 0000 0000 0000
2.5 如果符号有点不同,翻转第二个并执行加法。然而,由于在这种情况下相同,所以没什么可做的。
3 大减小
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm
y: 0 1000 0011 1010 1001 0000 0000 0000 0000
x: 0 1000 0011 110 0100 0000 0000 0000 0000 0
d: 0 1000 0011 0100 0101 0000 0000 0000 0000 0
4 调整 MSbit 为隐含的 1(移位“尾数”,递减指数)。
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm
d: 0 1000 0010 1000 1010 0000 0000 0000 0000
5 反向减法的帐户。 (翻转标志)
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm
d: 1 1000 0010 1000 1010 0000 0000 0000 0000
6 轮 - 在这种情况下没有值变化。
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm
d: 1 1000 0010 1000 1010 0000 0000 0000 0000
7 去除隐含位以形成编码结果。
s eeee eeee mmm mmmm mmmm mmmm mmmm mmmm
d: 1 1000 0010 000 1010 0000 0000 0000 0000
为简洁起见,省略了非数字、次法线、溢出、无穷大和舍入的详细信息。
注意 IEEE-754 使用“重要”,而不是“尾数”。
所以我有点无奈。我想我了解如何对 IEEE-754 数字进行加法运算,但我在减法方面遇到了很大的问题。我感觉,我的想法是对的,但是我想跟大家验证一下。
所以我们有以下两个 IEEE-754 编号:
x: 0 1000 0010 100 1000 0000 0000 0000 0000
y: 0 1000 0011 010 1001 0000 0000 0000 0000
因为我们必须要正数并且我们想减去它们,我的想法是取 y,反转尾数并计算
x+(-y)
一位导师告诉我,那是不正确的,我必须保持数字为正,然后减去它们。他为什么不告诉我,怎么不告诉我。
谁能告诉我正确的方法是什么?
我对 x-y 方式的想法:
- 将指数从 x 扩展到 1000 0011
- 将 x 的尾数移动 1
- 以正常方式将两个数相减
所有产生正确结果的方法都是正确的。通过从较大的绝对值中减去较小的绝对值并相应地调整符号位,舍入可能更容易处理。同样,使用正数只会使处理 1<<23 处的(可选)隐式数字变得稍微容易一些。对于负值,数字需要为 0xff800000。对于负非正规化,也会出现其他特殊情况。
OP 的 1-2-3 想法大部分是正确的,但可能错过了隐含的部分。
1 考虑隐含位。
s eeee eeee mmm mmmm mmmm mmmm mmmm mmmm
x: 0 1000 0010 100 1000 0000 0000 0000 0000
y: 0 1000 0011 010 1001 0000 0000 0000 0000
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm
x: 0 1000 0010 1100 1000 0000 0000 0000 0000
y: 0 1000 0011 1010 1001 0000 0000 0000 0000
2 调整较小的数量级,形成一个公共指数。 (增量博览会,转移“尾数”)
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm extra bits
x: 0 1000 0011 110 0100 0000 0000 0000 0000 0
y: 0 1000 0011 1010 1001 0000 0000 0000 0000
2.5 如果符号有点不同,翻转第二个并执行加法。然而,由于在这种情况下相同,所以没什么可做的。
3 大减小
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm
y: 0 1000 0011 1010 1001 0000 0000 0000 0000
x: 0 1000 0011 110 0100 0000 0000 0000 0000 0
d: 0 1000 0011 0100 0101 0000 0000 0000 0000 0
4 调整 MSbit 为隐含的 1(移位“尾数”,递减指数)。
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm
d: 0 1000 0010 1000 1010 0000 0000 0000 0000
5 反向减法的帐户。 (翻转标志)
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm
d: 1 1000 0010 1000 1010 0000 0000 0000 0000
6 轮 - 在这种情况下没有值变化。
s eeee eeee immm mmmm mmmm mmmm mmmm mmmm
d: 1 1000 0010 1000 1010 0000 0000 0000 0000
7 去除隐含位以形成编码结果。
s eeee eeee mmm mmmm mmmm mmmm mmmm mmmm
d: 1 1000 0010 000 1010 0000 0000 0000 0000
为简洁起见,省略了非数字、次法线、溢出、无穷大和舍入的详细信息。
注意 IEEE-754 使用“重要”,而不是“尾数”。