CSAPP:第2章 信息的表示和处理 2.2 整数表示

2.2 整数表示
1.整型数据类型
char, unsigned char(1字节), short, unsigned short(2字节),
int, unsigned(4字节), long, unsigned long(在64位windows是4字节,在64位linux/mac是8字节),
int32_t, uint32_t, int64_t, uint64_t(指定的固定位数,如16,32,64)(使用时需要先引入stdint.h头文件,如果需要使用N的最大最小值,可以用INT[N]_MIN和INT[N]MAX、UINT[N]MIN和UINT[N]MAX等)
int32_t 和 int64_t 是 C99标准引入的固定宽度整数类型,它们解决了传统整数类型(int、long、long long)大小不固定的问题,是编写可移植、可靠代码的重要工具。
某些C数据类型,特别是long型,在不同的机器上有不同的取值范围,而实际上C语言标准只指定了每种数据类型的最小范围,而不是确定的范围。
2.无符号数的编码
- B2U
3.补码编码
对于许多应用,我们还希望表示负数值。最常见的有符号数的计算机表示方式就是补码(two's-complement)形式。
在这个定义中,将字的最高有效位解释为负权(negative weight)。
- B2T:二进制最高位
-x*2^i,其他位+x*2^i,累加★

- T2B:若是正数,直接用原码;若是负数,高位是符号,其余位反码,加1
- 补码是将最高位
x*2^i取负再与其他位相加,原码是只相加其他位,根据最高位来判断符号,原码是最高位(x*2^i-1)再与其他位相加,即(负的)补码是原码+1,(负的)原码是补码-1。
4.有符号数和无符号数之间的转换
强制类型转换的结果保持位值不变,只是改变了解释这些位的方式。
- U2T
eg. (int)UINT32_MAX = -1。
- T2U

eg. T2U (-12 345)=-12 345+2^16=53191


5.C语言中的有符号数与无符号数
C语言中,要创建一个无符号常量,必须加上后缀字符 'u' 或者 'u', 例如, 12345U 或者 0x1A2Bu。
unsigned int: 123U 或 123u
long int: 123L 或 123l
unsigned long int: 123UL 或 123ul
long long int: 123LL 或 123ll
unsigned long long: 123ULL 或 123ull长整型常量:必须加后缀;对于浮点数:可选加后缀
123U // 必须:表示unsigned int
123L // 必须:表示long
3.14 // 有效:默认double类型
3.14f // 推荐:明确float类型
3.14F // 推荐:明确float类型(大写)
3.14l // 推荐:明确long double类型
3.14L // 推荐:明确long double类型(大写)
// 默认是double
// 所有没有后缀的浮点常量都是double类型
3.14 // double
1.0 // double
.5 // double
2e10 // double
C语言中不能写-2147483648:
// 编译器看到的:
-2147483648
// 实际解析为:
1. 先解析整数常量 "2147483648"
2. 然后应用一元负号 "-"
// 问题:2147483648 在32位系统中超出了int的范围!
// 对于32位int:范围是 -2147483648 到 2147483647
// 所以 2147483648 本身就不是有效的int常量6.扩展一个数字的位表示
补码数的符号扩展:用最高位补。
把 short 转换成 unsigned 时,我们先要改变大小,之后再完成从有符号到无符号的转换。也就是说 (unsigned) sx 等价于 (unsigned) (int) sx。
7.截断数字
- 截断无符号数:x' = x mod 2^k
- 截断补码数值:x' = U2T (x mod 2^k)(补码截断相当于先直接转为无符号模运算,再转回补码解释,因为可能变符号)
8.关于有符号数与无符号数的建议
- 除了 C 以外很少有语言支持无符号整数,如 Java 只支持有符号整数
>>:算术右移 → 高位补符号位(保持数的符号)>>>:逻辑右移 → 高位补0(总是产生非负数)
本文系作者 @xiin 原创发布在To Future$站点。未经许可,禁止转载。
暂无评论数据