csapp小笔记 整数的表示 c语言


博主水平有限,全文仅为摘录,如有错误,请不吝指出

整型数据类型

字节(byte)是计算机文件大小的基础单位,
位(bit)是计算计算机运算的基础.
1个字节由八个二进制组成,能表示0~255值的范围

整型数据类型在32/64位程序取值范围不同,具体如图所示:
csapp小笔记 整数的表示 c语言
csapp小笔记 整数的表示 c语言

无符号数的编码

定义:假设对于一个w位的无符号整数,用二进制比特位可以表示为[xw1x_{w-1} , xw2x_{w-2} , … ,x2x_2 , x1x_1 , x0x_0]。那么我们可以用一个函数表示如下:
csapp小笔记 整数的表示 c语言
使用示例如下:
csapp小笔记 整数的表示 c语言
我们也就可以得知能表示的最大值为:
UMaxwUMax_w\doteqi=0w1\displaystyle\sum_{i=0}^{w-1}2i2^i=2w12^w-1

补码编码

同样的,补码编码定义有:
对向量x=[xw1,xw2,,x2,x1,x0]\vec{x}=[x_{w-1} , x_{w-2} , … ,x_2 , x_1 , x_0]:
B2Tw(x)xw12w1+i=0w2B2T_w(\vec{x})\doteq-x_{w-1}2^{w-1}+\displaystyle\sum_{i=0}^{w-2}2i2^i
使用示例如下:
csapp小笔记 整数的表示 c语言
我们就可以得知能表示的最大值为:
TMaxwi=0w22i=2w11TMax_w\doteq\displaystyle\sum_{i=0}^{w-2}2^i=2^{w-1}-1
最小值有:
TMinw2w1TMin_w\doteq-2^{w-1}.

值得说明的是无论是无符号编码还是有符号编码全部都具有唯一性.

反码

除最高有效位为的权是(2w11)-(2^{w-1}-1)而不是2w1-2^{w-1},其余和补码是一样的:
B2Ow(x)xw1(2w11)+i=0w2xi2iB2O_w(\vec{x})\doteq-x_{w-1}(2^{w-1}-1)+\displaystyle\sum_{i=0}^{w-2}x_i2^i
(过去机器基于反码表示,但几乎所有的现代机器都使用补码了)

原码

最高有效位是符号位:
B2Sw(x)(1)xw1(i=0w2xi2i)B2S_w(\vec{x})\doteq(-1)^{x_{w-1}}*(\displaystyle\sum_{i=0}^{w-2}x_i2^i)
(浮点数中使用原码编码)

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

补码转换为无符号数

我们推导一下补码到无符号的转化,我们先将无符号编码和补码编码的公式相减,

B2Uw(x)B2Tw(x)=xw12w1(xw12w1)=xw12wB2U_w(\vec{x}) - B2T_w(\vec{x}) = x_{w-1}2^{w-1} - (-x_{w-1}2^{w-1}) = x_{w-1}2^w


B2Uw(x)=xw12w+B2Tw(x)B2U_w(\vec{x}) = x_{w-1}2^w + B2T_w(\vec{x})

令x为T2Bw(x),有:
  B2Uw(T2Bw(x)=xw12w+B2Tw(T2Bw(x))=x+xw12w+B2U_w(T2B_w(\vec{x}) = x_{w-1}2^w + B2T_w(T2B_w(\vec{x})) = x+x_{w-1}2^w +

即有:
  T2Uw(x)=xw12w+xT2U_w(\vec{x}) = x_{w-1}2^w + x

xw1x_w-1大于等于0时,则补码编码为正数,此时T2Uw(x)=xT2U_w(\vec{x}) = x

综上有csapp小笔记 整数的表示 c语言
  csapp小笔记 整数的表示 c语言

无符号数转换为补码

同样的,我们先将无符号编码和补码编码的公式相减,

B2Uw(x)B2Tw(x)=xw12w1(xw12w1)=xw12wB2U_w(\vec{x}) - B2T_w(\vec{x}) = x_{w-1}2^{w-1} - (-x_{w-1}2^{w-1}) = x_{w-1}2^w


B2Tw(x)=B2Uw(x)xw12wB2T_w(\vec{x})= B2U_w(\vec{x})-x_{w-1}2^w
uU2Bw(u),则 B2Tw(U2Bw(u))=B2Uw(U2Bw(u))uw12w=uuw12wB2T_w(U2B_w(\vec{u}))=B2U_w(U2B_w(\vec{u})) - u_{w-1}2^w = u - u_{w-1}2^w

U2Tw(u)=uuw12wU2T_w(u)=u - u_{w-1}2^w
而位uw1u_{w-1}决定是否大于TMaxw=2w11TMax_w=2^{w-1}-1,
即可得:
csapp小笔记 整数的表示 c语言
  csapp小笔记 整数的表示 c语言

扩展一个数字的位表示

零扩展

将一个无符号数转换为一个更大的数据类型,我们只需简单的在开头加00即可.

符号扩展

将补码数字转换为一个更大的数据类型
在开头加上符号位即可.

截断数字

截断无符号数

截断为k位有B2Uk([xk1,xk2,...,x0])B2U_k([x_{k-1},x_{k-2},...,x_0])=B2Uw([xw1,xw2,...,x0])B2U_w([x_{w-1},x_{w-2},...,x_0]) mod 2k2^k

截断补码

与截断无符号数相同只不过要将最高位转换为符号位.
截断为k位有
B2Tk([xk1,xk2,...,x0])B2T_k([x_{k-1},x_{k-2},...,x_0])=U2TkU2T_k(B2Uw([xw1,xw2,...,x0])B2U_w([x_{w-1},x_{w-2},...,x_0]) mod 2k)2^k)