二进制浮点加法的一些陷阱
Some pitfalls about floating point addition in binary
我有一些关于在二进制中添加两个浮点数的问题。谁能告诉我哪一步做错了?
下面是两个浮点数
sign exponent fraction
1 11101101 10000001101000011010011
0 11101110 01010100001001110010110
第一步。对齐指数(需要对齐大的)
1 11101110 11000000110100001101001 (exponet + 1 and shift right)
0 11101110 01010100001001110010110
第二步。四舍五入(因为我右移忽略number = 1/2,最低有效位是1,所以我们需要加1)
PS:此舍入规则在视频https://www.youtube.com/watch?v=wbxSTxhTmrs
当 9:33
第三步。加法(小数部分)
1.01010100001001110010110
- 0.11000000110100001101010 (add 1 for rounding up)
-------------------------------------------
1.00100110101011001011000
最后
因为1.00100110101011001011000
被归一化了,所以小数是00100110101011001011000
,指数是11101110
但指数的答案是 11101101
分数是 00100110101011001011001
我的每一步都有错吗?谢谢。
你的计算有几个错误,主要是忘记了隐藏的位和对不正确的位数进行计算。
A:1 11101101 (1).10000001101000011010011
B:0 11101110 (1).01010100001001110010110
第一步:
添加隐藏位
对齐指数
传递给二进制补码表示
请注意,当您将符号绝对值替换为 2 的补码时,您需要多一位。
A=exp(11101110) -(00.110000001101000011010011)
=exp(11101110) 11.001111110010111100101101
B=exp(11101110) 01.01010100001001110010110
第 2 步:执行加法
由于您的结果可能 >1(或(<-2),因此必须使用操作数符号扩展的额外位来完成。您之前不应执行操作数舍入。如果操作数接近且符号不同,您可能松散精度位。
(ca) 11 11111 1 1111 1 11
111.001111110010111100101101
+001.01010100001001110010110
-----------------------------
000.100100110101011001011001
第三步:重新归一化得到一个介于1和2之间的数,调整指数和变换数以符号绝对表示。
m=1.00100110101011001011001 exp=exp-1=11101101
第 4 步:舍入结果并根据需要重新归一化。
(此处无事可做)。
所以 m=(1).00100110101011001011001 exp=11101101
它给出了预期的结果。并且可以仔细检查。
#include <stdio.h>
int main(){
union floatint {
int i;
float f;
};
union floatint a;
a.i=0xf6C0D0D3;// 1111 0110 1100 0000 1101 0000 1101 0011
union floatint b;
b.i=0x772A1396;// 0111 0111 0010 1010 0001 0011 1001 0110
union floatint c;
c.f=a.f+b.f;
printf("0x%x\n",c.i);
// gives 0x76935659 = 0111 0110 1001 0011 0101 0110 0101 1001=0 11101101 00100110101011001011001
}
我有一些关于在二进制中添加两个浮点数的问题。谁能告诉我哪一步做错了?
下面是两个浮点数
sign exponent fraction
1 11101101 10000001101000011010011
0 11101110 01010100001001110010110
第一步。对齐指数(需要对齐大的)
1 11101110 11000000110100001101001 (exponet + 1 and shift right)
0 11101110 01010100001001110010110
第二步。四舍五入(因为我右移忽略number = 1/2,最低有效位是1,所以我们需要加1)
PS:此舍入规则在视频https://www.youtube.com/watch?v=wbxSTxhTmrs 当 9:33
第三步。加法(小数部分)
1.01010100001001110010110
- 0.11000000110100001101010 (add 1 for rounding up)
-------------------------------------------
1.00100110101011001011000
最后
因为1.00100110101011001011000
被归一化了,所以小数是00100110101011001011000
,指数是11101110
但指数的答案是 11101101
分数是 00100110101011001011001
我的每一步都有错吗?谢谢。
你的计算有几个错误,主要是忘记了隐藏的位和对不正确的位数进行计算。
A:1 11101101 (1).10000001101000011010011
B:0 11101110 (1).01010100001001110010110
第一步:
添加隐藏位
对齐指数
传递给二进制补码表示
请注意,当您将符号绝对值替换为 2 的补码时,您需要多一位。
A=exp(11101110) -(00.110000001101000011010011)
=exp(11101110) 11.001111110010111100101101
B=exp(11101110) 01.01010100001001110010110
第 2 步:执行加法
由于您的结果可能 >1(或(<-2),因此必须使用操作数符号扩展的额外位来完成。您之前不应执行操作数舍入。如果操作数接近且符号不同,您可能松散精度位。
(ca) 11 11111 1 1111 1 11
111.001111110010111100101101
+001.01010100001001110010110
-----------------------------
000.100100110101011001011001
第三步:重新归一化得到一个介于1和2之间的数,调整指数和变换数以符号绝对表示。
m=1.00100110101011001011001 exp=exp-1=11101101
第 4 步:舍入结果并根据需要重新归一化。
(此处无事可做)。
所以 m=(1).00100110101011001011001 exp=11101101
它给出了预期的结果。并且可以仔细检查。
#include <stdio.h>
int main(){
union floatint {
int i;
float f;
};
union floatint a;
a.i=0xf6C0D0D3;// 1111 0110 1100 0000 1101 0000 1101 0011
union floatint b;
b.i=0x772A1396;// 0111 0111 0010 1010 0001 0011 1001 0110
union floatint c;
c.f=a.f+b.f;
printf("0x%x\n",c.i);
// gives 0x76935659 = 0111 0110 1001 0011 0101 0110 0101 1001=0 11101101 00100110101011001011001
}