Logo
Published on

10.进制

Authors
  • avatar
    Name
    xiaobai
    Twitter

1. 进制转换与存储单位处理

1.1 标题

你正在开发一个文件管理工具,需要处理文件大小显示和网络下载时间计算。该工具需要支持不同进制的数据转换,并能准确处理存储单位和网络速度的单位换算。

1.2 内容

请实现以下三个函数:

1.2.1 进制转换函数

def convert_base(number_str, from_base, to_base):
    """
    进制转换函数

    参数:
        number_str: 数字字符串
        from_base: 源进制 (2-16)
        to_base: 目标进制 (2-16)

    返回:
        转换后的数字字符串

    示例:
        convert_base("255", 10, 16) -> "FF"
        convert_base("1010", 2, 10) -> "10"
    """

1.2.2 文件大小格式化函数

def format_file_size(size_bytes):
    """
    将字节数转换为人类可读的格式

    参数:
        size_bytes: 文件大小(字节)

    返回:
        格式化后的字符串,如 "1.50 KiB"

    要求:
        - 使用二进制前缀 (1024进制): B, KiB, MiB, GiB, TiB
        - 自动选择最合适的单位
        - 保留2位小数

    示例:
        format_file_size(1536) -> "1.50 KiB"
        format_file_size(1048576) -> "1.00 MiB"
    """

1.2.3 下载时间计算函数

def calculate_download_time(file_size_mb, bandwidth_mbps):
    """
    计算文件下载所需时间

    参数:
        file_size_mb: 文件大小(MB        bandwidth_mbps: 网络带宽(Mbps)

    返回:
        下载时间字符串,根据时间长短选择合适单位

    要求:
        - 正确进行单位换算(注意 Byte vs bit 的区别)
        - 小于1分钟显示秒,小于1小时显示分钟,否则显示小时
        - 保留1位小数

    示例:
        calculate_download_time(100, 50) -> "16.0 秒"
        calculate_download_time(2048, 100) -> "2.7 分钟"
    """

1.2.4 测试用例

# 测试数据
test_cases = [
    # 进制转换测试
    ("255", 10, 16),     # 应输出: "FF"
    ("1010", 2, 10),     # 应输出: "10"
    ("FF", 16, 2),       # 应输出: "11111111"

    # 文件大小测试
    (500,),              # 应输出: "500.00 B"
    (1536,),             # 应输出: "1.50 KiB"
    (1048576,),          # 应输出: "1.00 MiB"
    (3221225472,),       # 应输出: "3.00 GiB"

    # 下载时间测试
    (100, 50),           # 应输出: "16.0 秒"
    (2048, 100),         # 应输出: "2.7 分钟"
    (10240, 10),         # 应输出: "22.8 小时"
]

2. 参考答案

2.1 代码

# 定义进制转换函数
def convert_base(number_str, from_base, to_base):
    """
    进制转换函数

    参数:
        number_str: 数字字符串
        from_base: 源进制 (2-16)
        to_base: 目标进制 (2-16)

    返回:
        转换后的数字字符串
    """
    # 检查输入进制是否合法(2-16之间)
    if not (2 <= from_base <= 16 and 2 <= to_base <= 16):
        raise ValueError("进制必须在2-16之间")

    # 将输入数字字符串从原进制转换为十进制整数
    decimal_value = int(number_str, from_base)

    # 如果目标进制为10,直接返回对应的十进制字符串
    if to_base == 10:
        return str(decimal_value)

    # 定义一个内部函数,将十进制整数转换为任意目标进制字符串
    def int_to_base(n, base):
        # 如果数值为0,直接返回"0"
        if n == 0:
            return "0"
        # 进制表示的字符
        digits = "0123456789ABCDEF"
        result = ""
        # 逐步取余并拼接各位数字字符
        while n > 0:
            result = digits[n % base] + result
            n //= base
        return result

    # 返回最终目标进制的字符串
    return int_to_base(decimal_value, to_base)


# 定义文件大小格式化函数
def format_file_size(size_bytes):
    """
    将字节数转换为人类可读的格式

    参数:
        size_bytes: 文件大小(字节)

    返回:
        格式化后的字符串
    """
    # 文件大小不能为负数,抛出异常
    if size_bytes < 0:
        raise ValueError("文件大小不能为负数")

    # 定义文件大小单位(1024进制)
    units = ['B', 'KiB', 'MiB', 'GiB', 'TiB']
    # 转换为浮点数便于计算
    size = float(size_bytes)

    # 初始化单位索引
    unit_index = 0
    # 循环计算合适的单位,同时缩小size
    while size >= 1024 and unit_index < len(units) - 1:
        size /= 1024.0
        unit_index += 1

    # 返回两位小数的格式化字符串和单位
    return f"{size:.2f} {units[unit_index]}"


# 定义下载时间计算函数
def calculate_download_time(file_size_mb, bandwidth_mbps):
    """
    计算文件下载所需时间

    参数:
        file_size_mb: 文件大小(MB        bandwidth_mbps: 网络带宽(Mbps)

    返回:
        下载时间字符串
    """
    # 检查传入的文件大小和带宽都大于0
    if file_size_mb <= 0 or bandwidth_mbps <= 0:
        raise ValueError("文件大小和带宽必须大于0")

    # 文件大小从兆字节(MB)转换为兆比特(Mb):1 字节=8    file_size_mb_bits = file_size_mb * 8

    # 计算下载时间(秒)
    time_seconds = file_size_mb_bits / bandwidth_mbps

    # 根据总秒数判断选择合适的单位输出
    if time_seconds < 60:
        return f"{time_seconds:.1f} 秒"
    elif time_seconds < 3600:
        time_minutes = time_seconds / 60
        return f"{time_minutes:.1f} 分钟"
    else:
        time_hours = time_seconds / 3600
        return f"{time_hours:.1f} 小时"


# 进制转换测试用例
test_cases = [
    ("255", 10, 16, "FF"),
    ("1010", 2, 10, "10"),
    ("FF", 16, 2, "11111111")
]

# 遍历进制转换测试用例,分别调用转换函数并输出结果
for number, from_b, to_b, expected in test_cases:
    result = convert_base(number, from_b, to_b)
    print(f"{number} ({from_b}进制) -> {result} ({to_b}进制) [期望: {expected}]")

# 输出文件大小格式化测试分割线
print("\n=== 文件大小格式化测试 ===")

# 文件大小格式化测试用例
size_tests = [500, 1536, 1048576, 3221225472]
# 遍历文件大小测试用例,格式化并输出结果
for size in size_tests:
    result = format_file_size(size)
    print(f"{size:,} 字节 -> {result}")

# 输出下载时间计算测试分割线
print("\n=== 下载时间计算测试 ===")

# 下载时间计算测试用例
download_tests = [
    (100, 50, "16.0 秒"),
    (2048, 100, "2.7 分钟"),
    (10240, 10, "2.3 小时")
]

# 遍历下载时间测试用例,调用计算函数并输出结果
for file_size, bandwidth, expected in download_tests:
    result = calculate_download_time(file_size, bandwidth)
    print(f"{file_size} MB, {bandwidth} Mbps -> {result} [期望: {expected}]")

2.2 运行结果示例

255 (10进制) -> FF (16进制) [期望: FF]
1010 (2进制) -> 10 (10进制) [期望: 10]
FF (16进制) -> 11111111 (2进制) [期望: 11111111]

=== 文件大小格式化测试 ===
500 字节 -> 500.00 B
1,536 字节 -> 1.50 KiB
1,048,576 字节 -> 1.00 MiB
3,221,225,472 字节 -> 3.00 GiB

=== 下载时间计算测试 ===
100 MB, 50 Mbps -> 16.0[期望: 16.0]
2048 MB, 100 Mbps -> 2.7 分钟 [期望: 2.7 分钟]
10240 MB, 10 Mbps -> 2.3 小时 [期望: 2.3 小时]

2.3 知识点覆盖

  1. 进制转换int()函数的base参数使用、自定义进制转换算法
  2. 存储单位:二进制前缀(KiB, MiB, GiB)vs 十进制前缀的区别
  3. 单位换算:Byte vs bit的区别(1 Byte = 8 bits)
  4. 网络速度:Mbps到MB/s的换算
  5. 格式化输出:数字格式化、单位选择
  6. 边界处理:参数验证、异常处理
  7. 实际应用:文件管理、网络下载等真实场景