二进制转十进制
无符号数:
有符号数:
来源:湖大CS课题组(侵删)
对字长为w的负数x求补码:
法一:写出原码,除符号位外均变反,再+1。
法二:
法三:
来源:湖大CS课题组(侵删)
二者之间的转换:
有符号数 --> 无符号数:
反之:
举个例子就很好理解了:
1001:U=9,T=-7。
思考:若有一个w位的有符号数补码,想扩展k位,该怎么办(保证值不变)。
正数自不必说,原先的w位不变,w+1~w+k位为0即可。
负数:
扩展k位之后的补码:2^(w+k)-|x|
原先的补码:2^w-|x|
相差:2^(w+k)-|x|-(2^w-|x|)=2^w(2^k-1)
要使扩展后的值不变,|x|要加上上述相差的值
2^w(2^k-1):2^k-1就是111111(k个1),乘以2^w就是左移w位,右边以0补齐w位。
加上原来的补码值刚好将w个0补齐。
总结:扩展k个符号位。
eg.
-6:
4位补码:1110
扩展至8位:1111 1110
截断
一言以蔽之:高位被丢弃,只保留低位。
对于无符号数来说就是取模运算mod。
对于有符号数类似取模(可能要进行类型转换)。
无符号数加法UAdd
(忽略最高进位)
补码加法TAdd
“位”上的操作跟UAdd一样。
溢出情况处理:
来源:湖大CS课题组(侵删)
对于和>=2^(w-1)的称为正溢出,这时由于符号位因为进位的原因变为1所以结果为负数。
对于和<=-2^(w-1)-1的称为负溢出,这时由于符号位相加导致进位,并且最高位被舍弃成为正数。
无符号数乘法UMulti
两个w位的无符号数u,v相乘,得到2w位的结果,舍弃前w位。
UMulti(u,v)=u*v mod 2^w
有符号数乘法TMulti
与UMulti有相同的位级行为,只是需要修正。
TMulti(u,v)=U2T(u*v mod 2^w)
乘以常数
用移位(移一位就是乘二或除二)代替乘法:
eg.u*8 == u<<3
u<<5 - u<<3 == u*24
大部分的机器中移位和加法比乘法快很多。
除以常数
类似乘法
右移:
x>>k 等价于 x/2^k(注:向下取整)
想向上(向0)取整咋办?
1.真实结果不是小数的情况
不用取整
2.是小数
(x+(1<<k)-1)>>k修正,即((x+2^k-1)/2^k)向下取整(仅被除数为负数适用)