Lecture 6:知识 - 整数的表示与运算
408 学习笔记:Lecture 6:知识 - 整数的表示与运算。保留原有知识内容、公式与图示;有对应原件时提供查看和下载入口。
本页目录
描述:整数题的核心是“同一位模式、不同解释”。有符号整数通常按补码解释,无符号整数把全部位当数值位;类型转换往往不改低位位串,只改变保留、扩展或解释方式。
2.1 无符号与有符号整数
| 类型 | 编码 | $n$ 位范围 | 常见用途 |
|---|---|---|---|
| 无符号整数 | 全部位均为数值位,默认非负 | $0\sim2^n-1$ | 地址值、位掩码、对象大小及只产生非负值的计数 |
| 有符号整数 | 最高位参与符号,实际采用补码 | $-2^{n-1}\sim2^{n-1}-1$ | 普通整数运算 |
- 8 位无符号数范围是 $0\sim255$;8 位有符号补码整数范围是 $-128\sim127$。无符号数省掉符号位,因此同字长最大值更大。
- 无符号运算以模 $2^n$ 循环,例如最大无符号数加 1 回绕为 0。是否把这种回绕视为错误,取决于程序语义与语言规则。
- 计算机有符号整数采用补码:零唯一、符号位可与数值位一起参加加减、比原码/反码多表示一个最小负数。
2.2 C 语言整型及位模式
| 类型(常见实现) | 典型宽度 | 默认符号 | 说明 |
|---|---|---|---|
char |
8 bit / 1 B | 平台相关,题设若指定按其执行 | 用于字符或最小整数单位 |
short / short int |
16 bit / 2 B | signed |
短整型 |
int |
32 bit / 4 B | signed |
常用整型 |
long / long int |
32 或 64 bit | signed |
依 ABI 与平台变化 |
unsigned short/int/long |
对应类型宽度 | unsigned |
全部位解释为数值位 |
short、int、long未注明signed/unsigned时通常是有符号整数;具体宽度不能脱离题目或平台断言。- 有符号与无符号整型都以相同的二进制位模式参与存储和运算;差别在于解释规则、扩展方式和比较/溢出语义。
题型:#有符号无符号转换
在本讲默认的同字长、二进制补码机器模型中,有符号数转对应无符号类型通常表现为“位模式不变,只改变解释方式”。例如:
short x = -4321;
unsigned short y = (unsigned short)x; // y = 61215
x 的 16 位补码不变,作为无符号数解释即为 $2^{16}-4321=61215$。
- 从 C 语言的值语义看,有符号转无符号按模 $2^n$ 得到同余值;在补码机器上通常对应相同位串。反向把超出有符号范围的无符号值转成有符号类型时,结果依语言版本和实现规则处理,不能无条件概括为“只改解释”。
- 有符号与无符号数混合参与同一运算时,必须按 C 的具体整数提升与通常算术转换规则分析;当同等转换等级下无符号类型主导时,结果会按无符号语义解释。做 408 题需以题目给定的类型宽度和转换规则为准。
- 不要先把负数“改成正数”再算;应先确定参与运算时每个操作数提升/转换后的位宽和类型。
2.3 不同字长的转换
2.3.1 截断与扩展
| 方向 | 操作 | 结果 |
|---|---|---|
大字长 -> 小字长 |
固定位宽硬件/408 题中通常截掉多余高位,只保留低位 | 值可能改变;对目标无符号类型可按模 $2^k$ 理解 |
无符号小字长 -> 大字长 |
零扩展 | 高位补 0,数值保持不变 |
有符号小字长 -> 大字长 |
符号扩展 | 高位复制原符号位,补码真值保持不变 |
- 小字长向大字长的目标是尽量保持原数值:正数补 0,补码负数补 1。对无符号数,原最高位是数值位,故必须零扩展。
- C 语言中,超出目标范围的有符号窄化转换不应无条件写成“保留低位”:其结果可能由实现定义;无符号目标则按模 $2^k$ 规则确定。408 若明确采用固定补码截断模型,再按题设保留低位。
- 例如题设规定
char为 8 位无符号数时,char -> int应在高位补 0;若题设规定char是 signed,则应按符号扩展。 - 在题设明确采用固定补码位串重解释的机器模型中,同宽有符号/无符号转换可只改变位串的解释;若位宽扩大,先按源类型规则完成零扩展或符号扩展,再按目标类型解释。C 语言的有符号转无符号按模 $2^n$ 确定;反向转换若数值超出目标有符号范围,不能不加前提地视为必然重解释。
2.3.2 与浮点类型的联系
- 常见实现中
int和float均占 4 B,double占 8 B,但相同字节数不代表精度或编码相同。 - 整数转浮点在有效尾数位不足时会舍入;浮点转整数截掉小数部分,且若目标范围不够会发生无法表示的情况。具体分析见浮点数一讲。
题型:#位宽与转换跟踪
第一部分:固定步骤
- 写出源值在源字长下的完整二进制位串;负数必须先写补码。
- 判断是同宽重解释、缩窄截断,还是拓宽扩展。不要因目标类型为无符号就错误地给源负数“取绝对值”。
- 拓宽时先看源类型:无符号零扩展,有符号补码符号扩展;缩窄时,只有题设采用固定补码截断模型或目标为无符号类型,才可直接按保留低位计算。目标为有符号类型且结果超出范围时,还需按语言或题设规则判断。
- 最后按目标类型解释保留下来的位串,并检查后续表达式是否还会触发整数提升或有/无符号混合转换。
第二部分:典型例子
| 操作(假设) | 位级过程 | 结果 |
|---|---|---|
uint8_t 255 -> int32_t |
11111111 零扩展为 000...0011111111 |
$255$ |
int8_t -1 -> int32_t |
11111111 符号扩展为全 1 |
$-1$ |
int16_t -4321 -> uint16_t |
16 位模式不变,改变解释 | $65536-4321=61215$ |
int32_t 0x12345678 -> uint16_t |
截断高 16 位,仅保留 0x5678 |
$22136$ |
- 当运算的实际类型确为 $n$ 位无符号类型时,其结果按模 $2^n$ 定义;例如无符号 $0-1$ 得到 $2^n-1$。但
uint8_t、uint16_t等窄类型在 C 表达式中常先提升为int,要在赋值或强制转换回窄类型时才发生相应截断。 - 对有符号数,数学结果超出范围属于有符号溢出语义,不能因为硬件同样产生回绕位串就把它直接当作语言层面合法结果。
- 底层地址值、对象大小和位掩码常用无符号整数表示;C 指针本身是独立的指针类型,不应简单等同于无符号整数。指针差值使用
ptrdiff_t,边界与长度常涉及size_t,需按具体类型分析。 - 题中出现十六进制常量时,先按位写出再转换最稳妥:每个十六进制数码对应 4 位,避免在十进制与二进制之间反复心算导致漏位。
相关知识
- 科目导航:计算机组成原理导航
- 阅读顺序:上一篇:运算方法和运算电路 · 下一篇:存储器分类、层次结构与单位
2.4 本节复盘
- $n$ 位无符号数范围为 $[0,2^n-1]$,有符号补码整数范围为 $[-2^{n-1},2^{n-1}-1]$。
- 同一位串可表示不同数值;转换题先定目标类型和位宽,再判断是重解释、截断、零扩展还是符号扩展。
- 固定补码截断模型下,大转小保留低位;小转大时,无符号零扩展、有符号补码符号扩展。C 语言有符号窄化越界另依转换规则判断;
char的符号性必须看题设/平台。 - C 的混合有/无符号运算需先按类型提升与转换规则处理,不能只凭数学直觉判断。