目录
2.2 整数(Integer)表示
2.2.1 整型数据类型
32/64位程序上C语言int类型的取值范围:/(-2^{31}/)~/(2^{31}-1/)。unsigned int类型的取值范围:/(0/)~/(2^{32}-1/)。
有符号数据类型的取值范围是不对称的————负数的范围比正数大1。
C/C++都支持有符号和无符号数。Java只支持有符号数。
假设有一个整数数据类型有/(w/)位。其二进制编码可以用一个位向量/(/vec{x}/)来表示。
/(/vec{x}/) = [/(x_{w-1}, x_{w-2}, …, x_0/)]
2.2.2 无符号数编码
/(B2U_w(/vec{x})/)(Binary to Unsigned的缩写,长度为/(w/)) /(/equiv/) /(/sum_{i=0}^{w-1}{x_{i}2^{i}}/)。
定义无符号编码的最大值为/(UMax_w/) = /(2^w-1/)。
无符号数编码具有唯一性。(/(B2U_w/)是一个双射)
2.2.3 有符号数(补码two’s-complement)编码
最高有效位/(x_{w-1}/)称为符号位。
/(B2T_w(/vec{x})/)(Binary to Two’s-complement的缩写,长度为/(w/)) /(/equiv/) /(-x_{w-1}2^{w-1}+/sum_{i=0}^{w-2}{x_{i}2^{i}}/)。
由此可以推出/(w/)位补码所能表示的范围为/(-2^{w-1}/)~/(2^{w-1}-1/)。
定义最小补码值/(TMin_w/) = /(-2^{w-1}/),最大补码值/(TMax_w/) = /(2^{w-1}-1/)。显然,/(|TMin_w|/) = /(|TMax_w|/) + 1。
补码编码也具有唯一性。(/(B2T_w/)也是一个双射)(前提:在固定位数的表示范围内)
其他编码方式
2.2.4 有符号数和无符号数之间的转换
2.2.5 C语言中的有符号数和无符号数
几乎所有的机器都使用补码,并且大多数数字都默认为是有符号的。
如果要创建一个无符号常量,需要加上后缀字符’U’或者’u’。
当C语言执行一个运算时,只要有一个运算数是无符号的,那么C语言会隐式地将所有运算数都强制类型转换为无符号数,并假设这两个数都是非负的,来执行运算。(以32位字长为例)
2.2.6 扩展一个数字的位表示(增加位数)
无符号数的零扩展(zero extension)。
补码数的符号扩展(sign extension)。
2.2.7 截断(Truncate)数字(减小位数)
截断无符号数。
截断补码数值。
2.2.8 关于有符号数与无符号数的建议
隐式强制类型转换和无符号数据类型经常容易造成程序错误。
2.3 整数运算
2.3.1 无符号加法
当无符号加法运算溢出时,出现截断。
2.3.2 补码加法
2.3.3 补码的非
-x + x = 0
2.3.4 无符号乘法
2.3.5 补码乘法
2.3.6 乘以常数(2的幂)
编译器使用移位和加法运算的组合来代替乘以常数因子的乘法。
与2的幂相乘的无符号乘法
与2的幂相乘的补码乘法
2.3.7 除以2的幂
除以2的幂的无符号除法
除以2的幂的补码除法(向上舍入/向下舍入)
2.3.8 关于整数运算的最后思考
- 计算机执行的“整数”运算实际上是一种模运算形式。
- 表示数字的有限字长限制了可能的值的取值范围。
- 考虑运算结果溢出。
- 补码形式。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/288789.html