HNU2026-计算机系统-笔记 6 整数

6 整数

在计算机底层,所有的数据都是以 0 和 1 的二进制位(bit)形式存储的。计算机硬件本身并不知道这些 0 和 1 代表什么意义,因此我们需要建立一套**"解释规则"**,将二进制串映射为人类能够理解的整数。

1. 数据表示基础:无符号数与补码

为了满足不同的计算需求,计算机科学家设计了两种最基础的整数表示方式:

  • 无符号数(Unsigned)

    • 定义:只能表示 0 和正整数,没有负数。
    • 特点:所有的二进制位都代表正的权重。
    • 应用场景 :用于表示绝对不可能为负数的物理量或逻辑量,例如内存地址(指针)、文件大小、数组长度等。在 C 语言中对应 unsigned int 等类型。
  • 补码(Two's Complement)

    • 定义 :现代计算机默认的有符号数编码方式,可以表示正数、负数和 0。
    • 特点 :最高位(最左边的一位)被征用为符号位 ,但它不仅仅代表正负,而是代表一个巨大的负数权重
    • 应用场景 :用于日常的常规算术运算。在 C 语言中对应 int, short, long 等默认类型。

2. 核心映射规则:B2U 与 B2T

B2UB2T 是两个核心的数学函数,它们定义了如何将一个长度为 www 位的二进制序列 x⃗=[xw−1,xw−2,...,x0]\vec{x} = [x_{w-1}, x_{w-2}, \dots, x_0]x =[xw−1,xw−2,...,x0] 翻译成十进制整数。

2.1 B2U (Binary to Unsigned)

  • 原理 :每一位 xix_ixi 都代表一个正的权重 2i2^i2i。直接将所有位按权重相加。
  • 数学公式
    B2Uw(x⃗)=∑i=0w−1xi⋅2iB2U_w(\vec{x}) = \sum_{i=0}^{w-1} x_i \cdot 2^iB2Uw(x )=∑i=0w−1xi⋅2i

2.2 B2T (Binary to Two's Complement)

  • 原理 :最高位 xw−1x_{w-1}xw−1 的权重是负的 (−2w−1-2^{w-1}−2w−1),而其余所有位的权重依然是正的(2i2^i2i)。
  • 数学公式
    B2Tw(x⃗)=−xw−1⋅2w−1+∑i=0w−2xi⋅2iB2T_w(\vec{x}) = -x_{w-1} \cdot 2^{w-1} + \sum_{i=0}^{w-2} x_i \cdot 2^iB2Tw(x )=−xw−1⋅2w−1+∑i=0w−2xi⋅2i

💡 实例解析(以 4 位二进制 1011 为例,即 w=4w=4w=4)

  • 用 B2U 规则解释 :1⋅23+0⋅22+1⋅21+1⋅20=8+0+2+1=111 \cdot 2^3 + 0 \cdot 2^2 + 1 \cdot 2^1 + 1 \cdot 2^0 = 8 + 0 + 2 + 1 = 111⋅23+0⋅22+1⋅21+1⋅20=8+0+2+1=11
  • 用 B2T 规则解释 :−1⋅23+0⋅22+1⋅21+1⋅20=−8+0+2+1=−5-1 \cdot 2^3 + 0 \cdot 2^2 + 1 \cdot 2^1 + 1 \cdot 2^0 = -8 + 0 + 2 + 1 = -5−1⋅23+0⋅22+1⋅21+1⋅20=−8+0+2+1=−5

结论 :同样的底层二进制数据 1011,使用不同的解释规则,得到的值完全不同。


3. C 语言中的强制类型转换

在 C 语言中,我们经常会在有符号数(int)和无符号数(unsigned int)之间进行强制类型转换。

  • 核心本质底层二进制位(0 和 1)绝对不改变! 仅仅是改变了 CPU "看待"这些数据的方式。
  • 形象比喻 :相当于给 CPU 换了一副"眼镜"。内存里存的始终是 1011,戴上"补码眼镜"看到的是 -5,摘下换上"无符号眼镜"看到的就变成了 11
c 复制代码
int a = -5;               // 内存中存的二进制是 1011 (补码)
unsigned int b = (unsigned int)a; // 强制转换!内存依然是 1011,但 b 的值变成了 11

4. 转换的数值变化规律(T2U 与 U2T)

在有符号数(T)和无符号数(U)之间进行转换(即"正反向走")时,由于底层的位模式不变,数值的变化遵循严格的数学规律。假设数据总位数为 www:

4.1 规律一:最高位是 0(原本是正数或 0)

  • 变化结果数值完全不变
  • 原因 :最高位是 0 时,无论是 B2U 还是 B2T,最高位的权重(0⋅2w−10 \cdot 2^{w-1}0⋅2w−1 或 0⋅−2w−10 \cdot -2^{w-1}0⋅−2w−1)都是 0,其余位的计算方式完全一致。

4.2 规律二:最高位是 1(原本是负数,或无符号的大数)

  • 变化结果数值发生突变,且差值永远是 2w2^w2w
  • 原因 :最高位在无符号中是 +2w−1+2^{w-1}+2w−1,在补码中是 −2w−1-2^{w-1}−2w−1。两者的差值为 (+2w−1)−(−2w−1)=2w(+2^{w-1}) - (-2^{w-1}) = 2^w(+2w−1)−(−2w−1)=2w。

具体转换方向:

  • 方向 A:有符号 转 无符号 (T2U)

    • 现象:负数会变成一个极大的正数。
    • 公式 :新值=原值+2w新值 = 原值 + 2^w新值=原值+2w
    • 示例 (w=4w=4w=4):-5 转无符号 →−5+24=−5+16=11\rightarrow -5 + 2^4 = -5 + 16 = 11→−5+24=−5+16=11
  • 方向 B:无符号 转 有符号 (U2T)

    • 现象:极大的正数会突然变成负数。
    • 公式 :新值=原值−2w新值 = 原值 - 2^w新值=原值−2w
    • 示例 (w=4w=4w=4):11 转有符号 →11−24=11−16=−5\rightarrow 11 - 2^4 = 11 - 16 = -5→11−24=11−16=−5

避坑指南

在 C 语言编程中,尽量避免将有符号数和无符号数放在一起进行比较或运算

例如:0U - 1。由于 0U 是无符号数,-1 会被隐式转换为无符号数,其底层全为 1 的位模式会被解释为一个极其巨大的正数(在 32 位系统中为 4294967295),这往往是导致死循环或越界 Bug 的万恶之源。

C 语言中,对于 8 位有符号整数 b、c,c=-128,b=-c,则 b=-128

因为 c=10000000,对 c 取补(按位取反,+1),得出 b=10000000=-128

相关推荐
宵时待雨2 小时前
linux笔记归纳5:进程控制
linux·运维·笔记
中屹指纹浏览器2 小时前
2026浏览器缓存指纹持久化溯源机制与多层级缓存隔离优化方案
经验分享·笔记
羊群智妍2 小时前
2026 AI搜索优化技术实践:GEO监测工具选型报告
笔记
Tutankaaa3 小时前
从单场到多场并发:知识竞赛平台的弹性扩展能力
服务器·笔记·学习·职场和发展
sheeta19983 小时前
LeetCode 每日一题笔记 日期:2026.05.11 题目:2553. 分割数组中数字的数位
笔记·算法·leetcode
九思十安3 小时前
HNU2026-计算机系统-笔记 5 汇编进阶
汇编·笔记
奋斗的小乌龟3 小时前
langchain4j笔记-05
笔记
bukeyiwanshui3 小时前
20260512 docker笔记
linux·运维·笔记·docker·容器
奋斗的小乌龟4 小时前
langchain4j笔记-04
笔记