CC++ & Algorithm

进制转换大综合——二进制、八进制、十六进制任意转

困难2
语言版本:C++Python
概述:学会利用`int()`和`format()`在不同进制之间自由转换。

进制转换超简单!用Python打通二进制、八进制、十六进制任意转换

在计算机的世界里,数字的“语言”不止一种。我们平时用的0-9是十进制,但电脑内部只认0和1(二进制)。有时候为了简化书写,程序员还会用八进制(0-7)和十六进制(0-9和A-F)来记录长长的二进制数。比如,内存地址常用十六进制,文件权限用八进制。那么,怎样在它们之间自由切换呢?别怕,Python已经帮你准备好了“翻译官”——int()format(),再多进制也能轻松搞定。

1. 通用思路:先换成十进制这个“中转站”

想象一下,你手里有人民币(十进制)、美元(二进制)、欧元(八进制)、日元(十六进制)。想把一种货币换成另一种,最笨但最可靠的办法是:先换成世界通用货币——美元(十进制),再换成目标货币。进制转换也一样,任何进制先转十进制,再从十进制转目标进制

亲手算一算:八进制17转二进制

  • 第一步:八进制 17 转十进制
    八进制每一位的权重是8的幂次:1×8¹ + 7×8⁰ = 8 + 7 = 15
  • 第二步:十进制 15 转二进制
    自己算:15 ÷ 2 = 7 余1,7 ÷ 2 = 3 余1,3 ÷ 2 = 1 余1,1 ÷ 2 = 0 余1 → 从下往上写:1111
    用Python:bin(15) 输出 '0b1111'

这样手动算一次,你就明白了转换的底层逻辑。不过我们不需要每次都自己算,Python有现成的函数。

2. Python内置函数:一招吃遍所有进制

Python提供了几把“瑞士军刀”:

函数作用示例
int(字符串, 原进制)把任意进制字符串转成十进制整数int("1A", 16) → 26
bin(整数)十进制整数转二进制(带0b前缀)bin(26)'0b11010'
oct(整数)十进制整数转八进制(带0o前缀)oct(26)'0o32'
hex(整数)十进制整数转十六进制(带0x前缀)hex(26)'0x1a'

生活例子:你每周零花钱20元(十进制),想换成游戏里用的“金币”(假设是二进制),先用int把20变成十进制数字(20本身就是十进制),再用bin(20)得到'0b10100',代表你的20元相当于二进制10100个金币。

代码示例:十六进制 1A 转二进制

hex_str = "1A"                # 要转换的十六进制字符串
decimal = int(hex_str, 16)    # 先转十进制,得到26
binary = bin(decimal)         # 再转二进制,得到0b11010
print(binary)                 # 输出 0b11010

代码示例:二进制 11010 转八进制

bin_str = "11010"             # 要转换的二进制字符串
decimal = int(bin_str, 2)     # 先转十进制,得到26
octal = oct(decimal)          # 再转八进制,得到0o32
print(octal)                  # 输出 0o32

3. 用format()去掉烦人的前缀

bin()oct()hex()返回的字符串都带前缀(0b0o0x),有时候我们只要纯数字部分。这时候format()就派上用场了:

  • format(整数, 'b') → 二进制纯数字
  • format(整数, 'o') → 八进制纯数字
  • format(整数, 'x') → 十六进制纯数字(小写字母)
  • format(整数, 'X') → 十六进制纯数字(大写字母)
num = 26                      # 十进制整数26
print(format(num, 'b'))       # 输出 11010 (二进制)
print(format(num, 'o'))       # 输出 32 (八进制)
print(format(num, 'x'))       # 输出 1a (十六进制小写)
print(format(num, 'X'))       # 输出 1A (十六进制大写)

生活例子:班级排队,一共26个同学(十进制)。老师要用二进制编号记录,你给老师说“老师,用format(26, 'b')就能得到11010啦!”老师就不用每次写“0b”前缀了。

4. 自己动手写一个万能转换器(拓展)

如果你想更深入地理解转换过程,可以像搭积木一样,自己写一个函数:输入数字字符串、原进制、目标进制,输出目标进制的字符串。下面就是一个完整的实现,每一行都加了中文注释。

def convert_base(num_str, from_base, to_base):
    """
    将任意进制的数字字符串转换为目标进制的字符串
    :param num_str: 原进制下的数字字符串,如 "1A"
    :param from_base: 原进制(2~16)
    :param to_base: 目标进制(2~16)
    :return: 目标进制下的字符串,如 "11010"
    """
    # 先把原始字符串从原进制转为十进制整数
    decimal = int(num_str, from_base)
    
    # 如果转换结果是0,直接返回"0"
    if decimal == 0:
        return "0"
    
    # 准备一个字符表,用于处理超过9的进位(A~F)
    digits = "0123456789ABCDEF"
    result = ""                   # 存储结果字符串
    
    # 用“除目标进制取余”的方法,从低位到高位构建结果
    while decimal > 0:
        remainder = decimal % to_base   # 余数
        result = digits[remainder] + result  # 把余数对应的字符放到结果前面
        decimal //= to_base               # 去掉已经处理的最低位
    
    return result

# ---------- 测试 ----------
# 把十六进制"1A"转成二进制
print(convert_base("1A", 16, 2))   # 输出 11010

# 把二进制"11010"转成八进制
print(convert_base("11010", 2, 8)) # 输出 32

# 把十进制"26"转成十六进制
print(convert_base("26", 10, 16))  # 输出 1A

# 把八进制"32"转成十进制
print(convert_base("32", 8, 10))   # 输出 26

这个函数的工作原理:就像我们用手算二进制:不断除以目标进制,把余数记下来,最后倒序排列。你可以把它想象成“分糖果”:有26颗糖(十进制),要按每8颗一袋装(转八进制),装好3袋剩2颗(余数2),3袋再每8袋一盒……最后余数序列就是八进制结果。

5. 新手常犯的4个错误

❌ 错误1:忘记把数字写成字符串

int(17, 8) 这样写?不行!int()的第一个参数必须是字符串。正确的是 int("17", 8)
正确int("17", 8)

❌ 错误2:字符串里带了非法字符

比如写 int("1G", 16),十六进制最大是F,G超了,会报错 ValueError
正确int("1F", 16)

❌ 错误3:想用bin()转八进制或十六进制

bin()只能转二进制。想转八进制要用oct(),转十六进制用hex()
正确oct(decimal)hex(decimal)

❌ 错误4:format里进制代码写错了

format(26, 'd') 是转十进制,format(26, 'b')才是二进制。
小技巧:记一个口诀——binary(二)、octal(八)、x(十六),字母就是进制缩写。

6. 完整可运行示例:混合转换

下面这段代码,综合演示了从任意进制到任意进制的转换,并打印出中间步骤,方便你理解“十进制中转站”的思路。

# 演示:把十六进制"FF"转换成二进制,再转成八进制
hex_value = "FF"                            # 十六进制255
decimal = int(hex_value, 16)                # 转十进制:255
print(f"十六进制 {hex_value} 等于十进制 {decimal}")

binary = bin(decimal)                       # 转二进制:0b11111111
print(f"十进制 {decimal} 转二进制 = {binary}")

octal = oct(decimal)                        # 转八进制:0o377
print(f"十进制 {decimal} 转八进制 = {octal}")

# 用format去掉前缀,得到纯数字
print(f"纯二进制:{format(decimal, 'b')}")
print(f"纯八进制:{format(decimal, 'o')}")

# 另一种写法:直接从十六进制到二进制,不存中间变量
print(f"直接从十六进制{hex_value}得到二进制:{format(int(hex_value, 16), 'b')}")

运行结果:

十六进制 FF 等于十进制 255
十进制 255 转二进制 = 0b11111111
十进制 255 转八进制 = 0o377
纯二进制:11111111
纯八进制:377
直接从十六进制FF得到二进制:11111111

7. 学了这些,还能往哪走?

  • 任意进制判断:如何验证一个字符串是不是合法的二进制/八进制/十六进制?可以用int()配合异常捕获,或者正则表达式。
  • 浮点数的进制转换:小数部分(比如二进制0.1)怎么转?需要用到乘基取整法,以后可以深入学习。
  • 位运算:二进制的基本运算(与、或、异或、移位)是计算机底层的基础,对理解编程非常有帮助。
  • 进制与颜色值:网页颜色#FF0000就是十六进制的红,R=255 (FF), G=0, B=0,你能用今天的方法把十六进制转成十进制RGB吗?

进制转换就像在不同“数字语言”之间当翻译,掌握了int()format()这对黄金搭档,你就能轻松穿梭于二进制、八进制、十进制和十六进制之间。下次遇到文件权限(0o755)、内存地址(0x7fff)或者颜色代码(#1A2B3C),你就能自豪地说:“我知道怎么转换成十进制啦!”

例题精讲

1单选题

二进制数11010110转换为八进制数是多少?

A326
B336
C316
D346
2单选题

十六进制数2F转换为二进制数是多少?

A101111
B101011
C110111
D111011
3判断题

八进制数777转换为二进制数是111111111。

4填空题
将八进制字符串'17'转换为十六进制字符串。
代码:
oct_str = '17'
dec = int(oct_str, 8)
hex_str = ___
5填空题
将二进制字符串'1101'转换为八进制字符串。
代码:
bin_str = '1101'
dec = int(bin_str, 2)
oct_str = ___