Floating point 浮点运算中尾数的乘法
关于尾数(re),实际上如何将两个尾数相乘 假设IEEE 754单精度浮点表示 假设一个数字的尾数为Floating point 浮点运算中尾数的乘法,floating-point,hardware,fpu,Floating Point,Hardware,Fpu,关于尾数(re),实际上如何将两个尾数相乘 假设IEEE 754单精度浮点表示 假设一个数字的尾数为1.5,它将被编码为0b10000000000000000(十进制为4194304)。第二个数字的尾数为1.125,编码为0B00100000000000000(十进制为1048576) 1.5x1.125=1.6875 1.6875编码为0b10110000000000000000000(十进制为5767168)。但是4194304*1048576不等于5767168 尾数乘法是如何工作的,以至
1.5
,它将被编码为0b10000000000000000
(十进制为4194304
)。第二个数字的尾数为1.125
,编码为0B00100000000000000
(十进制为1048576
)
1.5x1.125=1.6875
1.6875
编码为0b10110000000000000000000
(十进制为5767168
)。但是4194304*1048576
不等于5767168
尾数乘法是如何工作的,以至于4194304
(1.5)乘以1048576
(1.125),得到5767168
(1.6875)
也就是说,如何将编码的尾数相乘
即,硬件如何使用存储在内存中的编码尾数来获取新值
从中,浮点数的乘法可以实现如下。我被困在第二步
编辑:由于问题被改写,所以将我的一些评论纳入了这个答案中
您链接的指南似乎描述了行为,但没有描述实现。如果实现如此简单,我会想象浮点运算会和整数运算一样快 对于尾数,硬件可能会在某个点做一些类似于添加隐藏位的事情,以便
0b110000000000000000000000 * 0b100100000000000000000000 = 0b11011000000000000000000000000000000000000000000
删除隐藏位并舍入尾随位后,该值变为0B10110000000000000
对于指数,硬件可以从两个因子的偏置指数中减去127,执行算术运算,然后将127加回和或差以重新偏置指数
请记住,64位格式用于对内存中的数字进行紧凑编码,但这可能不是执行数学运算时使用的实际表示形式。处理器甚至可以执行80位精度的中间数学运算,然后在将值写回内存时将结果四舍五入到64位。请参阅。您想要产品(1.0*2-1)*(1.0*2-3) 尾数是1和1,指数是-1和-3 因此尾数的乘积是1*1=1,指数之和是(-1)+(-3)=-4 因此,根据步骤1至4,两个因素的乘积为1*2-4=0.0625 需要记住两件重要的事情:(1)二进制IEEE 754浮点中的指数始终表示2的幂,(2)归一化尾数的整数部分始终为1(因此,为什么第一位可以隐藏在数字的实际二进制表示中)
编辑:由于问题被改写,所以将我的一些评论纳入了这个答案中
您链接的指南似乎描述了行为,但没有描述实现。如果实现如此简单,我会想象浮点运算会和整数运算一样快 对于尾数,硬件可能会在某个点做一些类似于添加隐藏位的事情,以便
0b110000000000000000000000 * 0b100100000000000000000000 = 0b11011000000000000000000000000000000000000000000
删除隐藏位并舍入尾随位后,该值变为0B10110000000000000
对于指数,硬件可以从两个因子的偏置指数中减去127,执行算术运算,然后将127加回和或差以重新偏置指数
请记住,64位格式用于对内存中的数字进行紧凑编码,但这可能不是执行数学运算时使用的实际表示形式。处理器甚至可以执行80位精度的中间数学运算,然后在将值写回内存时将结果四舍五入到64位。请参阅。我发现这回答了我的问题 为了乘以编码值,硬件不知何故忽略了跟踪零。还放置了一个前导一位 因此,对于1.5,使用了
0b11
(3)而不是0b10000000000000000
(4194304)。同样,对于1.125,使用
0b1001
(9)代替0B00100000000000000
(1048576)
因此0b11*0b1001=0b11011
(27)
如果忽略0b11011
中的额外前导一位*并添加尾随零,则以0b10110000000000000
结束(5767168)
*有关有效位的一些重要信息,请参见。对于本例,忽略额外的前导一位就足够了。我发现这回答了我的问题 为了乘以编码值,硬件不知何故忽略了跟踪零。还放置了一个前导一位 因此,对于1.5,使用了
0b11
(3)而不是0b10000000000000000
(4194304)。同样,对于1.125,使用
0b1001
(9)代替0B00100000000000000
(104
0x3FC0
0011111111000000
0 01111111 1000000
0x4040
0100000001000000
0 10000000 1000000
11
* 11
======
11
+11
======
1001
10.01
1.001 with an increase in the exponent.
0 10000001 001000....
010000001001000....
0100 0000 1001 000....
0x40900000
ab
* cd
======
ef
gh
======
jklm
e = a & d
f = b & d
g = a & c
h = b & c
nop0
ef
+ gh
======
jklm
xy cr
00 00
01 01
10 01
11 10
m = f
p = 0 because f+0 cant have a carry bit.
l = e xor h
o = e & h
k = o xor g
n = o & g
j = n
m = f = b & d
l = e xor h = (a&d) xor (b&c)
k = o xor g = (e & h) xor (a&c) = ((a&d) & (b&c)) xor (a&c)
j = n = o & g = (e & h) & (a&c) = ((a&d) & (b&c)) & (a&c)
0x3FF8000000000000 1.5
0x4008000000000000 3.0
0x4012000000000000 4.5
0011111111111000
0100000000001000
0100000000010010
0 01111111111 1000 1.1000...
0 10000000000 1000 1.1000...
0 10000000001 0010 1.0010....