原码是最直观的二进制表示方法,它直接使用最高位作为符号位(0表示正数,1表示负数),其余位表示数值的绝对值。在8位原码表示中:
这种表示方式虽然简单易懂,但存在两个明显问题:
实际工程中,原码很少直接用于算术运算,现代计算机主要使用补码表示法。
反码是对原码的改进:正数的反码与原码相同,负数的反码则是对其绝对值的原码按位取反(符号位保持为1)。例如:
反码解决了原码加减运算的部分问题,但仍然存在"双零"现象:
这种双零表示不仅浪费编码空间,还会导致比较运算的复杂性增加。
补码是现代计算机普遍采用的整数表示方法,它完美解决了原码和反码的问题:
补码的优势体现在:
补码转换技巧(以-69为例):
cpp复制原码:11000101 → 取反:00111010 → 加1:00111011 → 即69
所以补码10111011表示-69
位移是计算机中最高效的基本运算之一,与乘除法有直接对应关系:
示例(无符号数):
cpp复制00001010 (10) → 右移1位 → 00000101 (5)
00101100 (44) → 左移1位 → 01011000 (88)
在C++中,对于有符号数右移时,高位补符号位(算术右移);无符号数则是逻辑右移(高位补0)。
二进制小数转换为十进制时,小数部分每位代表2的负幂次:
code复制1101.101 =
1×2³ + 1×2² + 0×2¹ + 1×2⁰ + 1×2⁻¹ + 0×2⁻² + 1×2⁻³
= 8 + 4 + 0 + 1 + 0.5 + 0 + 0.125
= 13.625
实用转换步骤:
八进制每位对应3位二进制,转换时:
整数部分:
code复制35₈ = 3×8¹ + 5×8⁰ = 24 + 5 = 29₁₀
小数部分:
code复制0.6₈ = 6×8⁻¹ = 6/8 = 0.75₁₀
综合转换:
code复制35.6₈ = 29.75₁₀
记忆技巧:八进制转十进制时,整数部分从右到左位权为8⁰,8¹,8²...,小数部分从左到右为8⁻¹,8⁻²...
溢出(overflow)发生在运算结果超出数据类型表示范围时。CPU通过检测进位标志判断溢出:
判断标准:
code复制最高位的进位 ≠ 次高位的进位 → 溢出发生
示例(4位补码):
code复制0111 (+7) + 0001 (+1) = 1000 (-8) → 上溢
1000 (-8) + 1001 (-7) = 0001 (+1) → 下溢
位运算在底层编程中极为重要,常见操作:
cpp复制1010 | 1100 = 1110
// 应用:设置特定位为1
cpp复制1010 & 1100 = 1000
// 应用:检查特定位是否为1
cpp复制1010 ^ 1100 = 0110
// 应用:加密/解密,交换变量值
cpp复制~1010 = 0101
// 应用:创建掩码
数值表示范围:
特殊数值表示:
运算特性:
补码转换误区:
位移运算陷阱:
进制转换易错点:
补码转换口诀:
code复制看见补码要求值,
先看符号正或负。
若是负号不用慌,
取反加一得原量。
位运算速记:
code复制或(|)运算有1则1,
与(&)运算有0则0,
异或(^)相同则为0,
取反(~)全部翻转。
进制转换流程:
code复制其他进制转十进制:
整数小数分开算,
按权展开再相加。
十进制转其他进制:
整数除基取余数,
小数乘基取整部。
题目1:8位补码能表示的范围是?
code复制解析步骤:
1. 补码表示范围不对称
2. 最小:10000000 → -2⁷ = -128
3. 最大:01111111 → 2⁷-1 = +127
答案:-128到+127
题目2:将补码11101001转换为十进制
code复制解析步骤:
1. 首位1 → 负数
2. 取反:00010110
3. 加1:00010111 = 23
4. 加负号:-23
答案:-23
题目3:计算00101101 >> 2
code复制解析步骤:
1. 算术右移补符号位(0)
2. 第一次:00010110
3. 第二次:00001011
答案:00001011
8位原码表示中,-0的二进制形式是?
code复制答案:10000000
反码表示中,零有多少种表示?
code复制答案:2种(00000000和11111111)
补码10110110对应的十进制值是?
code复制解析:
1. 取反:01001001
2. 加1:01001010 = 74
3. 结果:-74
二进制数1101.101对应的八进制数是?
code复制解析:
1. 分组:001 101 . 101
2. 转换:15.5₈
35.6₈ + 12.4₈ = ? (八进制计算)
code复制解析:
1. 35.6₈ = 29.75₁₀
2. 12.4₈ = 10.5₁₀
3. 和:40.25₁₀ = 50.2₈
虽然GESP三级主要考察定点数,但了解浮点数有助于知识体系的完整:
IEEE 754单精度浮点格式:
code复制31 30-23 22-0
符号位 指数部分 尾数部分
特点:
补码设计的精妙之处在于模运算系统:
code复制对于n位二进制,模为2ⁿ
[x]补 = 2ⁿ + x (x为负数时)
这使得加减法可以统一处理:
code复制A - B = A + (-B) = A + [B]补 (mod 2ⁿ)
实际编程中的高效技巧:
cpp复制if (x & 1) { /* 奇数 */ }
cpp复制a ^= b; b ^= a; a ^= b;
cpp复制int abs(int x) {
int mask = x >> 31;
return (x ^ mask) - mask;
}
cpp复制int popcount(unsigned x) {
int count = 0;
while (x) {
x &= x - 1;
count++;
}
return count;
}
掌握这些底层表示和运算原理,不仅能帮助通过GESP认证考试,更能为后续学习计算机组成原理、操作系统等核心课程打下坚实基础。建议通过编写小程序实际验证各种数值表示和运算结果,加深理解。