C语言复习 进制转换

0. 核心规律与速查表

0.1 幂关系快捷转(必背)

  • 二进制 → 八进制:因为 (8 = 2^3)
    每 3 位二进制 ⇄ 1 位八进制
  • 二进制 → 十六进制:因为 (16 = 2^4)
    每 4 位二进制 ⇄ 1 位十六进制

口诀:“二转八看3位,二转十六看4位”


0.2 八进制/十六进制数字表(建议背熟)

八进制一位 ⇄ 二进制三位

八进制 二进制
0 000
1 001
2 010
3 011
4 100
5 101
6 110
7 111

十六进制一位 ⇄ 二进制四位

十六进制 十进制 二进制
0 0 0000
1 1 0001
2 2 0010
3 3 0011
4 4 0100
5 5 0101
6 6 0110
7 7 0111
8 8 1000
9 9 1001
A 10 1010
B 11 1011
C 12 1100
D 13 1101
E 14 1110
F 15 1111

1. 二转八(B → O)

1.1 规则

因为 (8=2^3),所以:

  • 整数部分:从右往左每 3 位一组,不足左侧补 0
  • 小数部分:从左往右每 3 位一组,不足右侧补 0

补 0 方向一定要对:
整数补左边,小数补右边。


1.2 例题

题:((101110111.110100)_2 = (?)_8)

分组:

  • 整数:101110111101 110 111
  • 小数:.110100.110 100

逐组换:

  • 101=5110=6111=7
  • .110=6100=4

所以:
[
(101110111.110100)_2 = (567.64)_8
]


1.3 补 0 示例

题:((11011.101)_2 = (?)_8)

  • 整数 1101111 011 → 左补 0:011 011
  • 小数 .101 已够 3 位

[
(011\ 011.101)_2 = (33.5)_8
]


2. 二转十六(B → H)

2.1 规则

因为 (16=2^4),所以:

  • 整数部分:从右往左每 4 位一组,不足左侧补 0
  • 小数部分:从左往右每 4 位一组,不足右侧补 0

2.2 例题

题:((000101110111.1101)2 = (?){16})

分组:

  • 整数:0001011101110001 0111 0111
  • 小数:.1101.1101

逐组换:

  • 0001=10111=70111=7
  • 1101=13=D

所以:
[
(000101110111.1101)2 = (177.D){16}
]


2.3 补 0 示例

题:((101011.11)2 = (?){16})

  • 整数 10101110 1011 → 左补 0:0010 1011
  • 小数 .11 → 右补 0:.1100

[
(0010\ 1011.1100)2 = (2B.C){16}
]


3. 十转二(D → B)

十进制转二进制分两块:

  • 整数部分:除 2 取余(倒着写)
  • 小数部分:乘 2 取整(顺着写)

3.1 整数部分:除 2 取余法

题:((124)_{10}=(?)_2)

运算 余数
124 ÷ 2 62 0
62 ÷ 2 31 0
31 ÷ 2 15 1
15 ÷ 2 7 1
7 ÷ 2 3 1
3 ÷ 2 1 1
1 ÷ 2 0 1

倒序余数:1111100

[
(124)_{10} = (1111100)_2
]


3.2 小数部分:乘 2 取整法

题:((0.25)_{10}=(?)_2)

运算 结果 取整 新小数
0.25 × 2 0.5 0 0.5
0.5 × 2 1.0 1 0

得到:.01

[
(0.25)_{10} = (0.01)_2
]


3.3 合并例题

[
(124.25)_{10} = (1111100.01)_2
]


3.4 提醒:小数可能无限循环

例如 (0.1_{10}) 转二进制是循环小数,题目常要求:

  • “保留 n 位”
  • 或写出循环形式

4. 十转八(D → O)

十转八分两块:

  • 整数:除 8 取余(倒写)
  • 小数:乘 8 取整(顺写)

4.1 整数部分:除 8 取余

题:((124)_{10}=(?)_8)

运算 余数
124 ÷ 8 15 4
15 ÷ 8 1 7
1 ÷ 8 0 1

倒序:174

[
(124)_{10} = (174)_8
]


4.2 小数部分:乘 8 取整

题:((0.25)_{10}=(?)_8)

运算 结果 取整 新小数
0.25 × 8 2.0 2 0

得到:.2

[
(0.25)_{10} = (0.2)_8
]


4.3 合并

[
(124.25)_{10} = (174.2)_8
]


5. 八转二(O → B)

5.1 规则(最简单)

八进制每 1 位对应二进制 3 位,直接逐位替换即可:

  • 整数部分从左到右替换
  • 小数部分从左到右替换

注意:中间位可以保留前导 0
最终写答案时,整数部分可以去掉最左侧多余 0。


5.2 例题(与前面二转八互相验证)

题:((567.64)_8 = (?)_2)

逐位替换:

  • 5 → 101
  • 6 → 110
  • 7 → 111
  • .6 → .110
  • 4 → 100

所以:
[
(567.64)_8 = (101110111.110100)_2
]


5.3 再来一个(含前导0情况)

题:((03.5)_8 = (?)_2)

  • 0 → 000
  • 3 → 011
  • .5 → .101

[
(03.5)_8 = (000011.101)_2 = (11.101)_2
]


6. 十六转二(H → B)

6.1 规则

十六进制每 1 位对应二进制 4 位,直接逐位替换即可。


6.2 例题(与前面二转十六互相验证)

题:((177.D)_{16}=(?)_2)

逐位替换:

  • 1 → 0001
  • 7 → 0111
  • 7 → 0111
  • .D → .1101

[
(177.D)_{16} = (000101110111.1101)_2
]


6.3 例题(全字母)

题:((2B.C)_{16}=(?)_2)

  • 2 → 0010
  • B → 1011
  • .C → .1100

[
(2B.C)_{16} = (00101011.1100)_2
]


7. 八十六(O ↔ H)互转技巧

7.1 通用且最稳的方法:走二进制中转

  • (O \to B):每位 3 bit
  • (H \to B):每位 4 bit
  • 然后 (B) 再分组转回来

不推荐直接“八 ↔ 十六”硬算,因为没有直接位对位关系;走二进制最省心。


7.2 示例:((256.4)8 \to (?){16})

1) 先八转二:
[
(256.4)_8 = (010\ 101\ 110.100)_2 = (10101110.100)_2
]

2) 再二转十六(4位分组):

  • 整数 101011101010 1110AE
  • 小数 .100 → 补0成 .10008

[
(256.4)8 = (AE.8){16}
]


8. 任意进制互转(通用方法)

这一节解决:(b) 进制 ↔ (c) 进制(不一定是 2/8/16)


8.1 任意进制 (b) → 十进制(权展开法)


[
(an a{n-1}\dots a0 . a{-1} a_{-2}\dots)b
]

[
\sum
{k=0}^{n} ak \cdot b^k + \sum{k=1}^{m} a_{-k} \cdot b^{-k}
]

示例:((1A3.F)_{16}) 转十进制

  • 整数:(1\cdot 16^2 + 10\cdot 16^1 + 3\cdot 16^0 = 256 + 160 + 3 = 419)
  • 小数:(F\cdot 16^{-1} = 15/16 = 0.9375)

[
(1A3.F){16} = (419.9375){10}
]


8.2 十进制 → 任意进制 (b)

8.2.1 整数部分:除 (b) 取余(倒写)

与“十转二/十转八”同理,把 2 或 8 换成基数 (b)。

8.2.2 小数部分:乘 (b) 取整(顺写)

与“十转二/十转八”同理,把 2 或 8 换成基数 (b)。

示例:((83.4)_{10}) 转五进制(保留 6 位五进制小数)

整数 83 → 5 进制:除5取余

  • 83 ÷ 5 = 16 余 3
  • 16 ÷ 5 = 3 余 1
  • 3 ÷ 5 = 0 余 3
    倒序:313

小数 0.4 → 5 进制:乘5取整

  • 0.4×5=2.0 取2,小数=0
    所以小数=.2

[
(83.4)_{10} = (313.2)_5
]


8.3 任意进制 (b) → 任意进制 (c)(两段法)

最通用:

1) 先 (b \to 10)
2) 再 (10 \to c)

如果目标是 8 或 16,也可以:(b\to 10\to 2\to 8/16),看题目哪个更顺。


8.4 数字符号范围(常见:2~36进制)

  • 0~9 表示 0~9
  • A~Z 表示 10~35
    例如:Z = 35

9. 负数表示:原码/反码/补码(两位补码)

这一节一定要先明确“位宽 n”(8位/16位/32位……)
因为同一个负数在不同位宽下的二进制表示不一样(高位会进行符号扩展)。


9.1 三种表示法对比(n 位)

设最高位为符号位(0正1负),其余 (n-1) 位表示数值。

9.1.1 原码(Sign-Magnitude)

  • 正数:符号位 0 + 绝对值二进制
  • 负数:符号位 1 + 绝对值二进制
  • 缺点:+0 和 -0 两个零,加减不方便

范围(n位):
[
-(2^{n-1}-1) \sim +(2^{n-1}-1)
]


9.1.2 反码(One's Complement)

  • 正数:同原码
  • 负数:在原码基础上,符号位不变,其余位按位取反
  • 缺点:仍有 +0 和 -0

范围同原码。


9.1.3 补码(Two's Complement,最常用)

  • 正数:与原码相同
  • 负数:绝对值的二进制(n位)→ 按位取反 → +1

特点:

  • 只有一个 0
  • 加减法统一用加法器实现(硬件友好)

范围(n位补码):
[
-2^{n-1} \sim 2^{n-1}-1
]


9.2 十进制负数 → n 位补码(最常考步骤)

要写 (-x) 的 n 位补码:

  1. 写出 (x) 的 n位二进制(不足补0)
  2. 按位取反
  3. 加 1(只保留 n 位)

例:求 8 位补码表示 (-37)

1) (+37) 的 8 位二进制:
37 = 32 + 4 + 1 → 0010 0101

2) 取反:1101 1010

3) +1:1101 1011

所以:
[
(-37)_{10} \text{ 的 8 位补码} = (11011011)_2
]


9.3 n 位补码 → 十进制(读数方法)

给你一个 n 位补码二进制,求十进制值:

  • 最高位=0:就是普通二进制值(正数)
  • 最高位=1:是负数,步骤:
    1) 全部位取反
    2) +1
    3) 得到绝对值,再加负号

例:8 位补码 1110 1011 转十进制

最高位是 1 → 负数
取反:0001 0100
+1:0001 0101 = 21
所以原数 = -21


9.4 符号扩展(Sign Extension)

当你把 n 位补码扩成更宽位数(比如 8 位 → 16 位)时:

  • 正数:高位补 0
  • 负数:高位补 1(补符号位)

例:8 位 11011011(-37)扩成 16 位:
[
11011011 \Rightarrow 11111111\ 11011011
]
即十六进制:0xFFDB


9.5 补码加减法与溢出(了解即可)

  • (a - b) 可以写成:(a + (-b))
  • 补码加法:直接相加,丢弃最高位进位(carry out)
  • 溢出判断(同号相加异号结果):
    • 两个正数相加得到负数 → 溢出
    • 两个负数相加得到正数 → 溢出

10. 补码与八/十六进制互转

10.1 原则:补码转八/十六 = “按位分组”,但要先明确位宽

补码本质是一串二进制位。

  • 转十六:每 4 位一组
  • 转八:每 3 位一组

关键点:位数凑不齐时不能随便补 0,要做“符号扩展补位”

  • 正数补 0
  • 负数补 1

10.2 示例:8 位补码 -37 转十六

已知:((-37)) 的 8 位补码是 11011011

分组 4 位:1101 1011D B

[
(-37){10} \text{(8位补码)} = (DB){16}
]

注意:DB 不是十六进制的“负号写法”,它是“在 8 位补码位宽下”的机器表示。


10.3 示例:8 位补码 -37 转八(需要先符号扩展凑 3 的倍数)

8 位是 3 的倍数吗?不是。
为了按 3 位分组,我们可以扩展到 9 位(符号扩展):

  • 原:11011011(负数,符号位 1)
  • 扩到 9 位:1 11011011111011011

分组:111 011 0117 3 3

[
(-37)_{10} \text{(用9位补码表达)} = (733)_8
]

同一个数,如果位宽不同,对应的八/十六表示也会变。
题目如果没说明位宽,一般默认 8 位/16 位。


10.4 从十六进制“机器码”读回十进制

例:给出 16 位十六进制 FFDB,问它表示的有符号十进制是多少?

1) 转二进制:
FFDB1111 1111 1101 1011

2) 最高位 1 → 负数,取反+1:

  • 取反:0000 0000 0010 0100
  • +1:0000 0000 0010 0101 = 37

所以表示:-37


11. 常见易错点

  1. 分组方向:整数从右往左,小数从左往右
  2. 补0方向:整数补左边,小数补右边
  3. 十六进制字母:A~F 对应 10~15
  4. 除法法则:除基取余,余数倒序
  5. 乘法法则:乘基取整,整数顺序
  6. 循环小数:十进制小数不一定能有限位表示
  7. 补码一定要看位宽:同一负数在 8/16/32 位下机器码不同
  8. 补码转八进制补位不能补0:负数要符号扩展补1

12. 练习题(含答案)

12.1 八转二

1) ((735.4)_8) 转二进制
答案:
7→111,3→011,5→101,.4→.100
[
(735.4)_8 = (111011101.100)_2
]


12.2 十六转二

1) ((3A7.F){16}) 转二进制
答案:
3→0011,A→1010,7→0111,.F→.1111
[
(3A7.F)
{16}=(001110100111.1111)_2
]


12.3 任意进制互转

1) ((1011.01)_2) 转十进制
答案:
(1011_2=11),(.01_2=1/4=0.25) → 11.25

2) ((1A3.F)_{16}) 转十进制
答案: 419.9375(见第 8.1 节)

3) ((83.4)_{10}) 转五进制
答案: ((313.2)_5)(见第 8.2 节)


12.4 补码题

1) 写出 (-21) 的 8 位补码
答案:
+21 = 00010101
取反 11101010
+1 → 11101011

2) 把 8 位补码 11101011 转回十进制
答案: -21(取反+1 得 21)

3) 16 位十六进制机器码 FFDB 表示的有符号十进制是多少?
答案: -37(见第 10.4 节)

上一篇 C语言复习 1月25日
下一篇 C语言复习 位运算 & | ^ ~ << >>
Keason

Keason管理员

flag{fkxqsVIVO50tmgbd}

本月创作热力图