当前位置: 首页 > news >正文

关于数据编码、进制、位运算的详细讲解(从属GESP三级)

本章内容

数据编码基础
进制转换
位运算基础

别让符号位绊住你的步伐,掌握补码,让加减法都成为加法。

一、 数据编码基础

目标:掌握 原码 / 反码 / 补码 的定义与互转、常见进制(2 / 8 / 10 / 16)互化方法,以及补码与位运算在实际运算中的意义与典型考点。


1 🧩 为什么需要 3 种编码?

编码

结构

主要特点

缺点 / 难点

卷面高频

原码

最高位为符号,剩余位为绝对值

真值直观,+0/-0 有两种表示

加减法需分正负两套电路

判断 ±0

反码

正数同原码;负数=符号位不变,其余位按位取反

减法可用加法+按位取反实现

仍有 ±0,并且要考虑进位回补

“反码=补码?”判断

补码

正数同原码;负数=反码+1

唯一零

,加减法统一,硬件最简单

表示范围不对称,最小负数无正值对应

范围、溢出、移位

记忆口诀

  • • 原→反:符号位不动,其余取反
  • • 反→补:末位 +1

2 🔍 数值范围与溢出

8 bit 有符号补码

  • • 最大:0111 1111₂ = 127₁₀
  • • 最小:1000 0000₂ = -128₁₀

判断补码加法溢出:符号位进位 ≠ 最高位进位 ➟ 溢出。考试常给二进制求和让你判断是否溢出。


3 📚 编码之间的快速互转

  1. 1. 十进制 → 原码
    写出绝对值的二进制,最高位加符号位(0 正 1 负)。
  2. 2. 原码 → 反码 / 补码
    负数才转换:原→反 取反,反→补 加1。
  3. 3. 补码 → 十进制
    若符号位 0,直接转;为 1 时先求反码,再求原码,最后取值加负号。

4✏️ 进制转换秒法

方向

方法

例题(历届真题)

16 → 8

先 16→2(4 位为 1 组),再 2→8(3 位为 1 组)

B2025₁₆ → 2620045₈

(2024-12 三级第 3 题)

10 → 2(整数)

连除 2 取余倒写

625₁₀ → 1001110001₂

(同卷第 4 题)

10 → 2(小数)

乘 2 取整顺写

0.8125₁₀ → 0.1101₂(2024-09 第 4 题)

技巧

  • 2⇄8:三位一拍手;2⇄16:四位抱成团。
  • • 带小数时,整数、⼩数部分分别转换再拼接。

5 📄 位运算与补码

运算

作用

典型考法

&

AND

清 0 / 掩码提取

a & 0x0F

取低 4 位

`

` OR

置 1 / 合并标志

^

XOR

取反 / 交换两数

见 2024-09 第 7 题“异或交换”

~

NOT

逐位取反

判断补码知识点

<<

>> 移位

<<

×2ⁿ,>>÷2ⁿ(算术右移保符号)

2024-12 第 6 题考负数右移


6 📁 历年高频考点总结

类别

高频问法

概念判断

“负数的反码和补码是否一样?”

2024-12 第 2 题

编码填空

给出 [10000011]原 = ( ? )

常见 8 bit 补码辨认

进制速算

二、八、十、十六互化

多次出现于 2023-06 / 2024-12 卷

位运算结果

5 & 3 == 0001

对错判定

2024-12 第 5 题

移位与符号

负数右移后结果

2024-12 第 6 题


7 🔔 易错点 & 备考建议

  1. 1. ±0 混淆:补码只有一个 0;原码/反码有两个。
  2. 2. 符号扩展:带符号右移请保留符号位。
  3. 3. 最小负数:如 -128 (1000 0000₂) 取反再加 1 会溢出,务必牢记。
  4. 4. 小数二进制:乘 2 取整过程别漏 0。
  5. 5. 移位优先级:位运算优先级低于算术运算,必要时加括号。

刷题顺序
① 读大纲关键词 → ② 按年份把对应题目做一遍 → ③ 归类错因 → ④ 30 min 速刷补码计算与进制互化练习。


8 📊 课后 5 分钟快练

  1. 1. 8 bit 补码 1111 1011₂ 表示的十进制数是?
  2. 2. 把 0.375₁₀ 写成二进制。
  3. 3. 判断:补码 1010 0000₂ >> 3 的结果是否仍为负数?
  4. 4. 将 7C3₁₆ 直接写成八进制。
  5. 5. 32-bit int a,执行 a ^= (1<<5); 的作用是什么?

小结:数据编码是连接计算机硬件与程序语义的“翻译官”。熟练掌握 原/反/补码进制转换,为后续位运算、整数溢出分析打下坚实基础。

二、进制转换


1 📌 进制概念一张表

基数

记号示例

用途/真题现身

二进制

(2)

0b1010

机器底层;真题常问“×××₁₀→₂” 或 “补码”

八进制

(8)

0371

(前导 0)

早期权限/颜色码;真题:B2025₁₆ → 2004526₈

十进制

(10)

123

人类日常

十六进制

(16)

0x1A3F

汇编、颜色、补码展示;真题常给 16→10、16→8


2 📈 整数部分的转换算法

2.1 十进制 → 任意基 b(除基取余)
vector<int> res;
while (N) { res.push_back(N % b); N /= b; }
reverse(res.begin(), res.end());
  • • 真题代码填空:decimal % 8; decimal /= 8;(十转八)
2.2 2 → 8 / 16(分组法)
  • • 每 3 位二进制 = 1 位八进制;每 4 位二进制 = 1 位十六进制。
  • • 23 级单选专门考“由低到高分组”
2.3 8 / 16 → 2(反向分组)
  • 7111₂F1111₂,再拼接;避免抄错高位补 0。

3 📉 小数部分的转换算法

方向

操作

真题示例

10 → 2/8/16

反复 乘基取整f*=b; digit=int(f); f-=digit;

0.8125₁₀ → 0.1101₂

2/8/16 → 10

Σ(数字×基^-位次)

101.11₂ = 5.75₁₀

(24-06-5)

循环小数:若乘基后出现循环余数,则出现循环节;考场通常限制精度或给定可整除样例(如 0.625)。


4 🔗 补码与负数(真题必考)

步骤

8 位示例:-5

原码

10000101

反码

负数:符号位不动,其余取反 → 11111010

补码

反码 + 1 → 11111011 → 真题选项 C 正确

考点 ① “补码简化硬件加减” 单选答案 B
考点 ② 补码范围:8 位有符号 -128~127 单选答案 A。


5 🖨️ C++ 常见实现与坑

5.1 标准库

功能

代码片段

字符串 → 整数

int x = std::stoi("FF", nullptr, 16);

整数 → 不同进制输出

cout << std::hex << n;

(真题填空选 cout<<hex<<decimal;

现代 C++17

std::from_chars / std::to_chars

支持 2–36 基数

陷阱

  1. 1. 前缀 0 输入被 cin八进制
  2. 2. std::hex 会一直影响后续输出,记得 cout<<std::dec; 恢复。
5.2 常用模板
string dec2hex(unsigned n){string s; const char *d="0123456789ABCDEF";do{ s.push_back(d[n&15]); n>>=4; }while(n);reverse(s.begin(),s.end()); return s;
}

6 ❌ 真题型“陷阱”速览

考法

代表题

关键点

速选结果

111.111₁₀

的二进制

整数、分数分别转换再合并(25-03-4)

代码填空

while 除 8 取余

递增 i++ 放在正确位置(24-06-4)

负数补码判断

8 位原/反/补对应

一位不同定律、符号位不动

“看位判断进制合法性”

输出四列 0/1(23-09 编程)

最大字符法快速判断可用进制


7 📄 速记口诀

“除基取余得整数,乘基取整求小数;三位八、四位十六,负数反补少一步!”


三、🔧 位运算基础

位运算(Bitwise Operation)=按二进制位直接进行的运算。


1 🎯 六大基本运算符

运算符

名称

二进制规则

&

按位 AND

1 & 1 → 1,其余 → 0

`

`

按位 OR

^

按位 XOR

相同 → 0,不同 → 1

~

(取反)

0 ↔ 1(单目)

<<

左移

整体向高位移,低位补 0

>>

右移

整体向低位移,符号位复制(有符号)或补 0(无符号)

优先级~ > << >> > & > ^ > |。常用括号防错。


2 💡 真值表速背

| A | B | A&B | A|B | A^B |
|---|---|-------|-------|-------|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 | 0 |


3 🧪 常见“位技巧”模板

目标

公式

说明

取第 k 位

(n >> k) & 1

右移到最低位后与 1 相与

置 1 第 k 位

`(n >> k)

1`

清 0 第 k 位

n &= ~(1 << k)

翻转第 k 位

n ^= (1 << k)

判断奇偶

n & 1

结果 0 → 偶,1 → 奇

低位快速乘 / 除 2ᵏ

n << k

/ n >> k

左移乘,右移除


4 🗂️ 典型真题拆解

真题问法

核心考点

一句答案

a = a & (a-1)

可实现什么?

去最低位 1

清掉最右侧 1(25-03-选择)

~(0x0F)

在 8 位结果?

取反

0xF0

int x=5; x<<1;

的值?

左移乘 2

10

(0b1101 >> 2)

逻辑右移

0b11

(即 3)

x ^ x

的结果?

XOR 自反

0


5 📌 移位细节

  1. 1. 符号位复制
    • int y = -8; y >> 1; → 仍为负(最高位补 1)。
    • • 若想逻辑右移用 无符号unsigned(y) >> 1
  1. 2. 超位宽移位
    • x << 32 在 32-bit UB。考题常问“结果未定义”。
  1. 3. 优先级
    • a & 1 << k ⇒ 实际为 a & (1<<k)? 需加括号

6 🕒 小方法(真题改编)

// 统计整数 n 的二进制 1 的个数(Brian–Kernighan)
int popcount(int n){int cnt=0;while(n){n &= n-1;  // 每次消掉最低 1cnt++;}return cnt;
}
// 真题:输入正整数,输出 1 的个数(24-12-编程)
// 交换变量最低两位
x = ((x & 1)<<1) | ((x & 2)>>1) | (x & ~3);
// 逻辑:提取第 0/1 位互换

7 ❌ 易错 TOP-4

易错

正确写法

x & 1 << k

(x & (1<<k))

忘记无符号逻辑右移

uint32_t y = x >> k;

把 XOR 当 OR

XOR 只在不同位 1

超位宽移位

先转 uint64_t 再移


8 ⭐ 速背口诀

与清零、或置位,异或翻转快如飞;移左乘、移右除,取位必须先括弧!


四、精选选择题 (10 题)

✅ 1. 【位运算 · 真题】

题目:设 unsigned x = 0xF0F0;,表达式 x & 0x0FF0 的结果为
A. 0xF0F0 B. 0x00F0 C. 0x0F00 D. 0xFF00
答案:C
解析

x      = 1111 0000 1111 0000
mask   = 0000 1111 1111 0000
AND    = 0000 1111 0000 0000 = 0x0F00

【出自:24 年 6 月选择题 3】


✅ 2. 【位运算】

题目:要把变量 n 的第 5 位(从 0 开始计)清 0,可使用下列哪条语句?
A. n &= ~(1 << 5); B. n |= ~(1 << 5);
C. n ^= ~(1 << 5); D. n |= (1 << 5);
答案:A
解析1<<5 得掩码 0x20,取反后第 5 位为 0,其余位 1;与运算可清 0 指定位。


✅ 3. 【位运算 · 真题】

题目:对于正整数 n,下列哪行代码可以快速判断 n 是否为 2 的整数次幂?
A. !(n & (n-1)) B. (n | (n-1)) == 0
C. (n ^ (n-1)) == 1 D. (n & (n+1)) == 0
答案:A
解析:若 n 为 2 的幂,则只有一个 1;n-1 把该 1 变成 0 且低位全 1,与运算结果为 0。
【出自:23 年 12 月选择题 6】


✅ 4. 【位运算】

题目:表达式 ((a & b) ^ (a | b)) 等价于下列哪个选项?
A. ~a B. a ^ b C. a & (~b) D. 0
答案:B
解析:集合恒等式:(A∩B) Δ (A∪B) = AΔB。按位逻辑等同。


✅ 5. 【位运算 · 真题】

题目:在 32 位带符号整数中,-1 >> 1 的值为
A. 0x7FFFFFFF B. 0xFFFFFFFF C. 0x00000000 D. 0x80000000
答案:B
解析:算术右移,符号位 1 保持,所有位补 1,结果仍为 -1。
【出自:24 年 9 月选择题 5】


✅ 6. 【位运算】

题目:以下哪一行代码可以交换 xy 两整数而不使用临时变量?
A. x = x + y; y = x - y; x = x - y;
B. x ^= y; y ^= x; x ^= y;
C. x = (x & y) | (x & ~y);
D. x |= y; y |= x; x |= y;
答案:B
解析:三次异或交换经典 trick;A 有溢出风险。


✅ 7. 【位运算 · 真题】

题目:8 位补码 11010100₂ 表示的十进制数是
A. -44 B. -44-1=-45 C. 44 D. 212
答案:A
解析:最高位 1 表负;求正值:~11010100+1=00101100=44,故结果 -44
【出自:25 年 3 月选择题 7】


✅ 8. 【位运算】

题目:若 unsigned char c = 0b00101101;,执行 c &= c-1;c 的值为
A. 0b00101100 B. 0b00101110 C. 0b00101101 D. 0b00101001
答案:A
解析c&(c-1) 清掉最低位 1。


✅ 9. 【位运算 · 真题】

题目:表达式 1 << 33 在 32 位编译环境下的行为是
A. 结果未定义(UB) B. 等于 0 C. 等于 2 D. 等于 4
答案:A
解析:移位位数 ≥ 类型宽度在 C++ 中属于未定义行为。
【出自:23 年 6 月选择题 11】


✅ 10. 【位运算】

题目:若想判断 x 是否为奇数,下列写法最有效率的是
A. x % 2 == 1 B. x & 1 C. x >> 1 << 1 != x D. (x^1) == x+1
答案:B
解析:按位与 1 直接取最低位,复杂度最小。


五、精选判断题 (10 题)

✅ 1. 【位运算 · 真题】

题目:在 C++ 中,a ^ a 的结果恒为 0。
答案:对
解析:异或同值消 0。
【出自:24 年 12 月判断题 9】


✅ 2. 【位运算】

题目:对于任意 unsigned int n,表达式 n << 1 等价于 n * 2
答案:对
解析:无符号左移一位相当于乘 2,且无溢出则数值相同。


✅ 3. 【位运算 · 真题】

题目:在 8 位补码中,~(0x00) 的值为 0xFF
答案:对
解析:按位取反,0→全 1。
【出自:23 年 9 月判断题 6】


✅ 4. 【位运算】

题目:若 xx-1 按位与后结果为 0,则 x 一定是 2 的幂。
答案:对
解析:仅 2 的幂拥有单独 1 位。


✅ 5. 【位运算】

题目:在带符号右移中,高位补 0 和补 1 的行为由编译器决定,与数据类型无关。
答案:错
解析:带符号整数右移遵循算术右移,高位补符号位;无符号右移逻辑补 0。


✅ 6. 【位运算 · 真题】

题目:表达式 ~(~x) 恒等于 x
答案:对
解析:两次按位非相当于原值。
【出自:24 年 6 月判断题 8】


✅ 7. 【位运算】

题目:交换两个整数时,三次异或法会改变原有的位模式顺序。
答案:错
解析:异或交换不丢位,只互换变量值。


✅ 8. 【位运算 · 真题】

题目:表达式 x & (~x) 的值恒为 0。
答案:对
解析x 与补码互补位无交集。
【出自:24 年 9 月判断题 10】


✅ 9. 【位运算】

题目:若 unsigned y = 1;,则 (y >> 1) == 0
答案:对
解析:逻辑右移一位低位被抛弃,高位补 0,得到 0。


✅ 10. 【位运算】

题目:把 n &= (n-1) 连续执行 k 次可清除 n 二进制表示中最右侧 k 个 1。
答案:对
解析:每执行一次消掉一位最右 1,迭代 k 次即可。


六、 精选编程题

✅ 1. 【位运算 · 真题】

题目回顾:输入 32 位无符号整数 N,输出其二进制中 1 的个数。


解题思路
  • 核心:利用 n &= n-1 每次消掉最低位 1,循环计数(Brian–Kernighan 算法)。
  • 复杂度:O(1) 空间,时间与 1 的个数成正比,最坏 32 次。
参考代码
#include <bits/stdc++.h>
using namespace std;int main() {uint32_t n;if (!(cin >> n)) return 0;int cnt = 0;while (n) {n &= (n - 1); // 消除最低位 1++cnt;}cout << cnt << '\n';return 0;
}

✅ 2. 【进制转换 · 编程】

题目回顾:将十进制正整数 X 转成基数 B(2 / 8 / 16)并输出。


解题思路
  • 方法:对 X 反复 X % B 记录余数,X /= B 更新,最后把余数逆序输出。
  • 字符映射:余数 0–15 映射到 "0123456789ABCDEF"
  • 复杂度:时间 O(log_B X),空间 O(log_B X) 存储结果字符。
参考代码
#include <bits/stdc++.h>
using namespace std;string convert(unsigned long long x, int base) {const char *dig = "0123456789ABCDEF";if (x == 0) return "0";string s;while (x) {s.push_back(dig[x % base]);x /= base;}reverse(s.begin(), s.end());return s;
}int main() {unsigned long long x; int b;if (!(cin >> x >> b)) return 0;cout << convert(x, b) << '\n';return 0;
}

相关文章:

  • 建筑证书兼职网站排名前50名免费的网站
  • 自己做的网站为何手机不能浏览免费网站安全软件大全
  • 中文网址的作用网络公司seo教程
  • 怎么做网站流量统计外链价格
  • 日照网站建设哪一家好松松软文
  • 顺义电大网上作业在那个网站做在百度如何发布作品
  • C#调用MATLAB函数
  • [Linux] Linux用户和组管理
  • 用福昕阅读器打开pdf文件,整个程序窗口自动缩小的问题
  • Python邮件自动化完全指南:从基础到高级应用
  • 如何通过nvm切换本地node环境详情教程(已装过node.js更改成nvm)
  • 【Game】Powerful——Pet Skin(13)
  • gitlab-ce安装
  • RISC-V三级流水线项目:总体概述和取指模块
  • 基于版本控制+WORM的OSS数据保护:防勒索攻击与法规遵从实践
  • 软件工程:从理论到实践,构建可靠软件的艺术与科学
  • iwebsec靶场-文件上传漏洞
  • JDK 1.8 Stream API:集合流处理深度解析
  • SQL关键字三分钟入门:UPDATE —— 修改数据
  • C++ 快速回顾(一)
  • 覆盖迁移工具选型、增量同步策略与数据一致性校验
  • 用字符打印中文字“里”
  • 芸众商城系统部署教程 接口报错500 芸众商城队列安装启动教程
  • Javaweb - 5 事件的绑定
  • Sping AI接入deepseek
  • 微信小程序中 rpx与px的区别