2.2 整数表示
2.2.1 整型数据类型
- 负数的范围比整数大1
2.2.2 无符号数的编码
对于向量
[vec{x}=[x_{w-1},x_{w-2},...,x_{0}]
]
存在
[B2U(vec{x})dot{=}sum_{i=0}^{w-1}{x_i2^i}
]
最大值为:
[UMax_wdot{=}sum_{i=0}^{w-1}2^i=2^w-1
]
最小值为:0
2.2.3 补码编码
对于向量:
[vec{x}=[x_{w-1},x_{w-2},...,x_{0}]
]
存在:
[B2T(vec{x})dot{=}-x_{w-1}2^{w-1}+sum_{i=0}^{w-2}{x_i2^i}
]
最高位有效位(x_{w-1})也称为符号位,它的“权重”为(-2^{w-1}),是无符号表示最高位的负数。
最大值:
[TMax_wdot{=}sum_{i=0}^{w-2}2^i=2^{w-1}-1
]
最小值:
[TMin_wdot{=}-2^{w-1}
]
Attention:
-
补码的范围是不对称的:(|TMin|=|TMax|+1)。
-
最大的无符号数之刚好比补码的最大值的两倍大一点:(UMax_w=2TMax_x+1)。
-
注意-1(有符号数,补码表示)和(UMax)有同样的位表示------一个全为1的串
数值0的无符号数和有符号数(补码)都是全0的串。
有符号数的其它表示方法:
-
反码(One's Complement):除了最高有效位的权是(-(2^{w-1}-1))而不是(-2^{w-1}),其它和补码一样:(B2O_w(vec{x})dot{=}-x_{w-1}(2^{w-1}-1)+sum_{i=0}^{w-2}{x_i2^i})
-
原码(Sign-Magnitude):最高有效位是符号位,剩下的位用来确定权值。
[B2S_w(vec{x})dot{=}(-1)^{x_{w-1}}sum_{i=0}^{w-2}{x_i2^i} ]
这两种方法有一个奇怪的属性,那就是对于数字0有两种不同的编码方法,其中[00...0]都解释为+0,而-0在原码中表示为[10...0],在反码中表示为[11...1]。但现代继器都用的补码。
2.2.4 有符号数和无符号数之间的转换
- 补码转换为无符号数
对于满足(TMin_wleq{x}leq{Tmax_w})的(x)有:
[T2U_w(x)=egin{cases} x+2^w,x<0\ x,xgeq0 end{cases}
]
- 无符号数转换为补码
对于满足(0leq{u}leq{UMax_w})的(u)有:
[U2T_w(u)=egin{cases} x-2^w,x>TMax_w\ x,xleq{TMax_w} end{cases}
]
2.2.5 C语言中的有符号数与无符号数
- c语言中,大多数字都默认是有符号的,要创建一个无符号常量,必须加上后缀字符‘U’或者‘u’。
- 当执行一个运算时,若一个运算数是有符号的,而另一个运算数是无符号的,那么C语言会隐式的将有符号强制类型转换为无符号数。
2.2.6 扩展一个数字的位表示
- 无符号数的零扩展
- 有符号数的符号扩展
- 从一个数据大小到另一个数据大小的转换,以及无符号和有符号数之间的转换的相对顺序能够影响到一个程序的行为,具体参见P56。
2.2.7 截断数字
- 截断无符号数:
[dot{x}=x mod 2^k
]
- 截断有符号数:
[dot{x}=U2T_k(x mod 2^k)
]