补码和无符号数


文章总结自《深入理解计算机系统》第三版


符号解释:
u——无符号数
t——有符号数
UMax——无符号最大值
TMax——有符号最大值
TMin——有符号最小值
+ux——加无符号数
+tx——加有符号数
在这里插入图片描述
注意:

  • |TMin|=|TMax|+1,补码范围不对称,TMin没有与之对应的正数
  • UMax=2TMax+1,最大的无符号数值比补码最大值的两倍大1
  • -1和UMax有同样的位表示——全1串
  • 数值0在两表示方法中相同——全0串

一、有符号数和无符号数之间的转换

规则:位模式不变,数值可能改变,位模式是补码和无符号数的桥梁。

补码转化为无符号数

假定无符号数和补码的形式都为w位
对于TMin≤x≤TMax的x来说
T 2 U ( x ) = { x + 2 w , x<0 x , x≥0 T2U(x) =\begin{cases} x+2^w ,\text{x<0}\\ x,\text{x≥0} \end{cases} T2U(x)={x+2w,x<0x,x≥0

推导:对于w位二进制,补码的最高位权重为-2(w-1),当按照位模式不变转化为无符号数时,最高位权重变为2(w-1),对于数值为负的补码,相当于加上2×2(w-1)=2w,对于数值非负的补码数,最高位为0,和无符号数数值相等。

无符号数转化为补码

对于0≤x≤UMax,的u有
U 2 T ( u ) = { u , u≤TMax u − 2 w , u>TMax U2T(u) =\begin{cases} u ,\text{u≤TMax}\\ u-2^w,\text{u>TMax} \end{cases} U2T(u)={u,u≤TMaxu2w,u>TMax
推导:对于u≤TMax的u,最高位为0,与对应补码的值相等,u>TMax的u,最高位为1,减去权重之差。

二、不同字长整数间的转换

扩展数字的位(用于将较小类型转换为较大类型)

无符号数的零扩展
直接高位填0

补码数的符号扩展
推导:对于符号位为0,将扩展位全0,很明显数值不会变。对于符号位为1,将扩展位全1,假设有一个w位二进制,符号位权重-2(w-1),假设扩展一位,符号位权重-2w,下一位权重由-2(w-1)变为2(w-1),那么数值变化为-2w+2×2(w-1)=0。

截断数字(将较大类型转换为较小类型)

截断无符号数和补码数值,均将高位截去。大多数情况值均会变化,不过对于补码的某些情况值不会变。

C语言中的有符号数与无符号数

声明一个常量,默认为有符号数;无符号数的表示需要加上后缀u或U。对于同时包含有符号数和无符号数表达式的处理方式是,隐式地将有符号数转化为无符号数。这将造成问题。这里特别注意无符号数经运算后成为负数的情况,当其变为负数,采用补码的形式,但其值是无符号数的形式,值将特别大。规避这种错误的方法是绝不使用无符号数(Java中是这么做的)。

double sum(float a[],unsigned length)
{
     double result=0.0;
     for(int i=0;i<=length-1;i++)
           result+=a[i]
     return result;
}

这里length作为无符号数传入,当length传入实参0时,length-1=-1,其位模式为0xFFFF(32位),但表示成巨大无符号数为232-1。

注意:在位数和有无符号两者同时需要转换的情况下,C语言先改变大小,再完成由无符号的转变。

三、整数的运算

常说算术运算溢出,指的是完整的整数结果不能放到数据类型的字长中去。而溢出时,是将高位截去。

无符号数加法

对于满足0≤x,y<2w
x + u y = { x + y , x + y < 2 w x + y − 2 w , 2 w ≤ x + y < 2 ( w + 1 ) x+^uy =\begin{cases} x+y ,&{x+y<2^w}\\ x+y-2^w,&{2^w≤x+y<2^{(w+1 )}} \end{cases} x+uy={x+y,x+y2w,x+y<2w2wx+y<2(w+1)

推导:w位二进制的UMax=2w-1,0≤x+y<2(w+1),不超过UMax,正常表示为x+y,超过UMax(且最多超出一位),截去高位,即w+1位,相当于减去数2w

检测无符号数加法的溢出

x + u y 溢 出 , 当 且 仅 当 x + y < x ( y ) x+^uy 溢出,当且仅当x+y<x(y) x+uyx+y<x(y)
推导:不溢出时,x+y肯定大于x(y)
溢出则
x+y=x+y-2w,
y<UMax=2w,
y-2w<0,
x+y<x。

补码加法(正溢出和负溢出)

对于满足-2(w-1)≤x,y≤2w-1-1

x + t y = { x + y − 2 w , 2 ( w − 1 ) ≤ x + y x + y , − 2 ( w − 1 ) ≤ x + y < 2 ( w − 1 ) x + y + 2 w , x + y < − 2 ( w − 1 ) x+^ty=\left\{ \begin{array}{rcl} x+y-2^w,&{2^{(w-1)}≤x+y}\\ x+y,&{-2^{(w-1)}≤x+y<2^{(w-1)}}\\ x+y+2^w,& {x+y<-2^{(w-1)}}\\ \end{array} \right. x+ty=x+y2w,x+y,x+y+2w,2(w1)x+y2(w1)x+y<2(w1)x+y<2(w1)

推导:w位二进制的TMin=-2(w-1),TMax=2(w-1)-1, 2×TMin≤x+y≤2×TMax,即-2w≤x+y≤2w-2,
当x+y超过TMax时,正溢出,截断时从和数中减去2w,当x+y小于TMin,负溢出,截断时和数加上2w。下图为一个正溢出的例子,位权的变化导致数值得变化。
在这里插入图片描述
在这里插入图片描述
检测补码加法的溢出
当x>0,y>0,x+y<0时,发生正溢出
当x<0,y<0,x+y>0时,发生负溢出

无符号数求反

0≤x<2w任意x,为使得-x+x=0
− u x = { x , x = 0 2 w − x , x > 0 -^ux =\begin{cases} x,&{x=0}\\ 2^w-x,&{x>0} \end{cases} ux={x,2wx,x=0x>0
推导:当x>时,(2w-x)+x=2w,这将导致无符号数溢出,二进制全0,数值为0;当x=0时例外,是因为2x-0=2x,这个数无法用w位二进制表示,同时0+0=0也复合求反的要求。

补码求反

2w-1≤x<2w-1,任意x求-x,使得-x+x=0
− t x = { T M i n , x = T M i n − x , x > T M i n -^tx =\begin{cases} TMin,&{x=TMin}\\ -x,&{x>TMin} \end{cases} tx={TMin,x,x=TMinx>TMin
推导:对于x>TMin的x,都可以用w位补码的形式表示出其相反数,而TMin没有,因此使用TMin+TMin=-2(w-1)+(-2(w-1))=-2w,负溢出。

无符号乘法与补码乘法

对应都是位模式相乘,再截取多余的位
在这里插入图片描述
无符号和补码的相乘、截断后的位模式相同,解释的方式不同

四、乘以常数

机器乘法指令相当慢,需要10以上的时钟周期,而加法、减法、位级运算、移位只需要一个时钟周期。且使用移位和加法可代替常数因子乘法。

乘以2的幂

x×2t直接对位模式左移t位,溢出高位截取,补码和无符号的形式均相同,只是解释不同。
且一个非2的幂的数,可分解为多个2的幂的和。例如,
14=23+22+21=1110,对应位模式(x<<3)+(x<<2)+(x<<1)
14=24-21,对应位模式(x<<4)-(x<<1)

除以2的幂

无符号除法
乘以2的幂相同,只不过是位模式逻辑右移,同时需注意全部向下取整

补码除法
位模式算术右移,不过可实现向下取整,向零取整
对于w位补码数值x,右移0≤k<w,直接算术右移x>>k,将导致向下取整
在这里插入图片描述
另一种情况,移位之前加一个“偏置”,即(x+(1<<k)-1)>>k,将导致向零取整
在这里插入图片描述

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值