CSAPP

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_tint64_tC99标准引入的固定宽度整数类型,它们解决了传统整数类型(intlonglong long)大小不固定的问题,是编写可移植、可靠代码的重要工具。

某些C数据类型,特别是long型,在不同的机器上有不同的取值范围,而实际上C语言标准只指定了每种数据类型的最小范围,而不是确定的范围。

2.无符号数的编码

  • B2U

3.补码编码

对于许多应用,我们还希望表示负数值。最常见的有符号数的计算机表示方式就是补码(two's-complement)形式。

在这个定义中,将字的最高有效位解释为负权(negative weight)。

  • B2T:二进制最高位 -x*2^i,其他位 +x*2^i,累加★

2025-12-03T14:18:12.png

  • T2B:若是正数,直接用原码;若是负数,高位是符号,其余位反码,加1
  • 补码是将最高位x*2^i取负再与其他位相加,原码是只相加其他位,根据最高位来判断符号,原码是最高位(x*2^i-1)再与其他位相加,即(负的)补码是原码+1,(负的)原码是补码-1。

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

强制类型转换的结果保持位值不变,只是改变了解释这些位的方式。

  • U2T

eg. (int)UINT32_MAX = -1。

  • T2U

图片3

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

2025-12-03T14:18:55.png

2025-12-03T14:19:06.png

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

2025-12-03T14:19:21.png

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(总是产生非负数)
分类: CS-Basics 标签: CSAPP

评论

暂无评论数据

暂无评论数据

目录