CC++ & Algorithm

进制转换

中等0
语言版本:C++
概述:学习如何把数字从一种进制变成另一种进制,就像把不同颜色的糖果按规则重新排列。

进制转换:数字的“换装”游戏

你每天用的数字都是“十进制”——0、1、2……9,满十进一。但计算机的世界里,数字还有别的“穿法”:二进制(只有0和1)、八进制(0到7)、十六进制(0到9和A、B、C、D、E、F)。进制转换就像给数字换衣服——你可以把一个十进制数,按照规则变成二进制、八进制、十六进制,或者反过来。学懂它,你就知道计算机是怎么存数字、怎么算加减的了,以后学位运算也会轻松很多。


为什么需要不同的进制?

  • 生活里:我们习惯十进制,因为人有十根手指。但计算机只有“开”和“关”两种状态,所以它用二进制(0和1)。
  • 八进制和十六进制:是为了让人更方便地表示长长的二进制数。比如二进制11111111写成长串很累,但转成十六进制就是FF,两个字母搞定。颜色的RGB值(如#FF00FF)就是用十六进制表示的。
  • 类比糖果:假设你有10颗糖,想按“2颗一组”分装,剩下的单独放。分完之后,组数就是高位,剩下的就是低位。十进制是“10颗一组”,二进制是“2颗一组”。所以10(十进制)转成二进制就是1010,因为10颗糖能分5组(余0),5组又能分2组(余1),2组分1组(余0),最后1组不能再分(余1),倒过来看就是1010。

1. 十进制转其他进制(“除基取余法”)

这是最核心的方法:不断除以目标进制(基数),记录每次的余数,最后把余数从下往上读。

十进制转二进制举例:把十进制数 10 转二进制

10 ÷ 2 = 5 余 0
5 ÷ 2 = 2 余 1
2 ÷ 2 = 1 余 0
1 ÷ 2 = 0 余 1   (商为0时停止)

余数从下往上:1010 → 就是二进制结果。

手写函数(保留原代码并加上注释):

def decimal_to_binary(n):
    """把十进制整数n转换成二进制字符串"""
    if n == 0:
        return "0"
    result = ""  # 用来拼接余数
    while n > 0:
        result = str(n % 2) + result  # 余数拼到左边
        n = n // 2  # 整除2,继续下一轮
    return result

# 测试
print(decimal_to_binary(10))  # 输出 1010

十进制转八进制、十六进制也同理

比如把 255 转十六进制:

255 ÷ 16 = 15 余 15 → 十六进制里15是 F
15 ÷ 16 = 0 余 15 → F
结果:FF

但要注意:当余数大于9时,要映射成字母AF(对应1015)。所以要写通用函数,处理10~15。

Python内置函数直接转换

  • bin(10)'0b1010'0b前缀表示二进制)
  • oct(10)'0o12'0o前缀表示八进制)
  • hex(255)'0xff'0x前缀表示十六进制)

如果只想要纯数字串,可以用切片去掉前缀:bin(10)[2:]'1010'


2. 其他进制转十进制(“位权展开法”)

每个数位上的数字,乘以该位对应的“权重”(基数^位置),再全部加起来。

  • 二进制 1010 转十进制:

    • 从右往左,第0位(个位)权重是 20=12^0=1,第1位权重 21=22^1=2,第2位 22=42^2=4,第3位 23=82^3=8
    • 计算:1×8+0×4+1×2+0×1=101 \times 8 + 0 \times 4 + 1 \times 2 + 0 \times 1 = 10
  • 十六进制 FF 转十进制:

    • F是15,最右边是第0位:15×160=1515 \times 16^0 = 15;左边第1位:15×161=24015 \times 16^1 = 240;总和255。

Python里用int(字符串, 进制)一步搞定:

int("1010", 2)   # → 10
int("FF", 16)    # → 255
int("17", 8)     # → 15(因为八进制17 = 1×8 + 7 = 15)

3. 自己写一个通用的进制转换函数

你可以把“十进制→任意进制”封装成一个函数,支持2~16进制。下面这个例子,再把“任意进制→十进制”也写出来,方便对比。

def decimal_to_base(n, base):
    """把十进制整数n转换成任意进制(2<=base<=16)的字符串"""
    if n == 0:
        return "0"
    digits = "0123456789ABCDEF"  # 0~15对应的字符
    result = ""
    while n > 0:
        remainder = n % base          # 余数(数值0~base-1)
        result = digits[remainder] + result  # 用对应字符拼到左边
        n = n // base                 # 缩小基数倍
    return result

def base_to_decimal(s, base):
    """把任意进制字符串s(2<=base<=16)转换成十进制整数"""
    digits = "0123456789ABCDEF"
    decimal = 0
    # 从最高位开始处理
    for ch in s:
        value = digits.index(ch.upper())  # 找出字符对应的数值
        decimal = decimal * base + value   # 用霍纳法(Horner)累加
    return decimal

# ----- 测试 -----
print(decimal_to_base(10, 2))    # 输出 1010
print(decimal_to_base(255, 16))  # 输出 FF
print(base_to_decimal("1010", 2))# 输出 10
print(base_to_decimal("FF", 16)) # 输出 255

生活中的小例子:你有零花钱45元(十进制),按二进制表示就是101101,因为32+8+4+1=45。用函数算一下:

print(decimal_to_base(45, 2))  # 输出 101101

4. 新手常犯的错误

  • 余数顺序写反:有人喜欢把余数写在右边,得到0101(十进制10的错误结果)。记住:从下往上读,或者代码里把它拼到左边。
  • 忘记处理0:如果输入n=0,直接返回"0",而不能返回空字符串。
  • 十六进制字母大小写混淆:Python里int("FF", 16)可以,但int("ff", 16)也行。但自己写的函数要统一处理大小写,比如转成大写。
  • 基数搞错:比如二进制里出现数字2,那就不合法。int函数会报错。检查输入。
  • 负数的转换:上面的代码只适用于非负整数。带符号负数需要额外处理(通常用补码表示),不过这个以后再学。

5. 完整可运行示例

把以上知识点整合成一个程序,演示几个日常数字的转换:

# 进制转换演示程序
def decimal_to_base(n, base):
    """十进制转任意进制(2~16),返回字符串"""
    if n == 0:
        return "0"
    digits = "0123456789ABCDEF"
    result = ""
    while n > 0:
        remainder = n % base
        result = digits[remainder] + result
        n = n // base
    return result

def base_to_decimal(s, base):
    """任意进制字符串转十进制整数"""
    digits = "0123456789ABCDEF"
    decimal = 0
    for ch in s:
        value = digits.index(ch.upper())
        decimal = decimal * base + value
    return decimal

# ---- 测试数据 ----
test_numbers = [0, 7, 10, 15, 100, 255]

print("十进制 → 二进制 → 八进制 → 十六进制")
for num in test_numbers:
    b = decimal_to_base(num, 2)
    o = decimal_to_base(num, 8)
    h = decimal_to_base(num, 16)
    print(f"{num:3d}{b:>8s}{o:>3s}{h:>2s}")

print("\n反过来验证:")
print("二进制 1010 转十进制:", base_to_decimal("1010", 2))  # 10
print("八进制 17 转十进制:", base_to_decimal("17", 8))      # 15
print("十六进制 FF 转十进制:", base_to_decimal("FF", 16))   # 255

运行结果:

十进制 → 二进制 → 八进制 → 十六进制
  0 →        0 →   0 →  0
  7 →      111 →   7 →  7
 10 →     1010 →  12 →  A
 15 →     1111 →  17 →  F
100 →  1100100 → 144 → 64
255 → 11111111 → 377 → FF

反过来验证:
二进制 1010 转十进制: 10
八进制 17 转十进制: 15
十六进制 FF 转十进制: 255

6. 相关知识点指引

学完进制转换,你可以向更深的方向探索:

  • 位运算:与、或、异或、左移、右移,这些操作直接基于二进制,能帮你写出更高效的代码(比如判断奇偶、乘以2的幂)。
  • 计算机数据存储:整数在内存中是用补码的二进制表示的,了解原码、反码、补码会很有意思。
  • 颜色表示:网页上的颜色#RRGGBB就是十六进制,比如#FF0000是红色,#00FF00是绿色。你可以写个程序把RGB(0-255)转成十六进制字符串。
  • ASCII码:字符在计算机里其实是一个数字(0-127),比如大写字母A是65,转成二进制就是01000001
  • 任意进制之间的互转:可以先把A进制转十进制,再转成B进制,这就是通用方法。

进制转换就像数字的“换装”游戏,掌握了它,你就能更懂计算机的心跳啦!

例题精讲

1单选题

二进制数1011转换为十进制是多少?

A11
B13
C14
D10
2判断题

十进制数255转换成十六进制是FF。

3填空题
补全以下Python函数,将十进制整数n转换为二进制字符串(n≥0):
def dec_to_bin(n):
    if n == 0:
        return "0"
    else:
        return ___
4单选题

十六进制数A3转换为十进制是多少?

A163
B160
C173
D153
5判断题

八进制数77转换为十进制是63。