C 获取两个无符号整数(HW)相乘的32高位
我正在阅读CSAPP并试图完成家庭作业问题。假设w=32,2.75表示将两个32位无符号整数相乘得到高32位。给定函数C 获取两个无符号整数(HW)相乘的32高位,c,bits,C,Bits,我正在阅读CSAPP并试图完成家庭作业问题。假设w=32,2.75表示将两个32位无符号整数相乘得到高32位。给定函数int signed\u high\u prod(int x,int y),该函数计算x的高阶32位。对于x和y为二补形式的情况int-signed\u-high\u-prod(int-x,int-y)应用于实现unsigned-int-unsigned\u-high\u-prod(unsigned-x,unsigned-y) 通过谷歌搜索,我发现x'.y'=x.y+x.y_31
int signed\u high\u prod(int x,int y)
,该函数计算x的高阶32位。对于x和y为二补形式的情况int-signed\u-high\u-prod(int-x,int-y)
应用于实现unsigned-int-unsigned\u-high\u-prod(unsigned-x,unsigned-y)
通过谷歌搜索,我发现x'.y'=x.y+x.y_31.2^32+y.x_31.2^32+x_31.2^64
,其中x'和y'分别是x和y的无符号形式
我还是不明白答案
unsigned unsigned_high_prod(unsigned x, unsigned y){
unsigned p = (unsigned) signed_high_prod((int) x, (int) y)
if((int) x < 0){
p += y;
}
if((int) y < 0){
p += x;
}
return p;
}
unsigned unsigned\u high\u产品(unsigned x,unsigned y){
无符号p=(无符号)有符号高输出((int)x,(int)y)
如果((int)x<0){
p+=y;
}
如果((int)y<0){
p+=x;
}
返回p;
}
为什么最后一个术语对结果没有影响?为什么
x<0
那么x\u 31=1
,加上y
?和y
一样,要将一个有符号的,2的补码,32位整数转换成一个无符号的32位整数,如果它是负数,我们在它的值上加2
signed_high_prod
执行有符号乘法并返回乘积的第63位到第32位。我们希望unsigned\u high\u prod
对无符号乘法执行相同的操作,并使用signed\u high\u prod
然后补偿无符号乘法和有符号乘法之间的差异
Let N(i) = { 1, i < 0
{ 0, i >= 0
Let U(i) = i + N(i)·2³² { −2³¹ <= i < 2³¹ }
由于对无符号、32位整数的算术运算将以模2执行,因此我们有:
⌊U(x)·U(y)/2³²⌋ mod 2³² = (⌊x·y/2³²⌋ + x·N(y) + y·N(x) + N(x)·N(y)·2³²) mod 2³²
= (⌊x·y/2³²⌋ + x·N(y) + y·N(x)) mod 2³²
我相信这是由
unsigned_high_prod
函数执行的计算的原因。要将带符号的2的补码32位整数转换为无符号的32位整数,如果它是负数,我们将其值加2
signed_high_prod
执行有符号乘法并返回乘积的第63位到第32位。我们希望unsigned\u high\u prod
对无符号乘法执行相同的操作,并使用signed\u high\u prod
然后补偿无符号乘法和有符号乘法之间的差异
Let N(i) = { 1, i < 0
{ 0, i >= 0
Let U(i) = i + N(i)·2³² { −2³¹ <= i < 2³¹ }
由于对无符号、32位整数的算术运算将以模2执行,因此我们有:
⌊U(x)·U(y)/2³²⌋ mod 2³² = (⌊x·y/2³²⌋ + x·N(y) + y·N(x) + N(x)·N(y)·2³²) mod 2³²
= (⌊x·y/2³²⌋ + x·N(y) + y·N(x)) mod 2³²
我认为这是由
unsigned\u high\u prod
函数执行的计算的原因。要执行位级乘法,我们必须首先扩展位,然后进行一系列移位和加法。例如,假设w=3,让x=[011]
和y=[101]
。(即x=3
和y=-3(有符号)或5(无符号)
)
为了执行无符号乘积,我们首先进行如下零扩展:(忽略位6及以上)
因此,无符号高位为[001]
为执行已签署的产品,我们首先签署如下扩展:
000 011
* 111 101
--------
000 011
+ 001 100
+ 011 000 **
+ 110 000 **
+ 100 000 **
--------
110 111
========
因此,有符号高位是[110]
注意,有符号和无符号高位之间的区别(如上面**所示)是我们在有符号的情况下添加了[111]*[011]
。因此,我们必须减去这个量才能得到无符号高阶位
The unsigned high order bits = [110] - [111] * [011]
= [110] - [101]
= [110] + [011] ??
= [001] (as above)
由于[111]=-1
,因此校正量-[111]*[011]
相当于-(-1*x)=x
因此,当y
为负值时(如本例中),我们必须通过添加x
来更正结果。同样,当x
为负时,我们必须通过添加y
来更正结果
-[101]=~[101]+1=[010]+[001]=[011]
要执行位级乘法,我们必须首先扩展位,然后进行一系列移位和加法。例如,假设w=3,让x=[011]
和y=[101]
。(即x=3
和y=-3(有符号)或5(无符号)
)
为了执行无符号乘积,我们首先进行如下零扩展:(忽略位6及以上)
因此,无符号高位为[001]
为执行已签署的产品,我们首先签署如下扩展:
000 011
* 111 101
--------
000 011
+ 001 100
+ 011 000 **
+ 110 000 **
+ 100 000 **
--------
110 111
========
因此,有符号高位是[110]
注意,有符号和无符号高位之间的区别(如上面**所示)是我们在有符号的情况下添加了[111]*[011]
。因此,我们必须减去这个量才能得到无符号高阶位
The unsigned high order bits = [110] - [111] * [011]
= [110] - [101]
= [110] + [011] ??
= [001] (as above)
由于[111]=-1
,因此校正量-[111]*[011]
相当于-(-1*x)=x
因此,当y
为负值时(如本例中),我们必须通过添加x
来更正结果。同样,当x
为负时,我们必须通过添加y
来更正结果
-[101]=~[101]+1=[010]+[001]=[011]
- x'.y'=x.y+x.y_31.2^32+y.x_31.2^32+x_31.y_31.2^64