Python实现十进制整数与BCD码转换

Python实现十进制整数与BCD码转换

BCD码

8421BCD码是最基本和最常用的BCD码,它和四位自然二进制码相似,各位的权值为8、4、2、1,故称为有权BCD码。和四位自然二进制码不同的是,它只选用了四位二进制码中前10组代码,即用0000~1001分别代表它所对应的十进制数,余下的六组代码不用。

例如: 十进制数128的BCD码为0001 0010 1000,即0x128

算法原理

  • 十进制转BCD码

    十进制数转BCD码的本质将十进制数转化为相同数字的十六进制数,即十进制数128转化为0x128。那么如何将128转化为0x128呢?只需要 8 ∗ 1 6 0 + 2 ∗ 1 6 1 + 1 ∗ 1 6 2 = 296 = 0 x 128 = 000100101000 8*16^0+2*16^1+1*16^2=296=0x128=000100101000 8160+2161+1162=296=0x128=000100101000,依此类推。示例代码利用Python字符串切片分别取出1、2、8三个数字

  • BCD码转十进制

    BCD码转十进制的本质就是将十六进制数转化为相同数字的十进制数,即十六进制数0x128(即000100101000)转化为128。那么如何将0x128转化为128呢?只需要 8 ∗ 1 0 0 + 2 ∗ 1 0 1 + 1 ∗ 1 0 2 = 128 8*10^0+2*10^1+1*10^2=128 8100+2101+1102=128,依此类推。示例代码利用移位运算>>后与0x0f相与&,分别取出1、2、8三个数字

示例代码

def dec2bcd(dec: int, lenth: int = 19) -> str:
    """十进制正整数转指定长度BCD码

    Args:
        data (int): 十进制正整数
        lenth (int, optional): 指定长度(高位补0). Defaults to 19.

    Raises:
        TypeError: 输入非正整数!
        OverflowError: 输入十进制数过大,超过BCD码指定长度

    Returns:
        str: 返回BCD码字符串
    """
    if not isinstance(dec, int) or dec < 0:
        raise TypeError("输入非正整数!")

    bcd = 0
    for index, char in enumerate(str(dec)[::-1]):
        bcd += int(char) * 16**index

    # 转化为二进制字符串,高位补0
    pattern = f"{bcd:0{lenth}b}"

    if len(pattern) > lenth:
        raise OverflowError("输入十进制数过大,超过BCD码指定长度")

    return ",".join(code for code in pattern)
def bcd2dec(data: str) -> int:
    """BCD码转十进制正整数

    Args:
        data (str): 二进制BCD码,如"10101101"

    Raises:
        TypeError: 输入非字符串!
        ValueError: 输入非二进制字符串!

    Returns:
        int: 返回十进制正整数
    """
    if not isinstance(data, str):
        raise TypeError("输入非字符串!")

    for num in data:
        if num not in ["0", "1"]:
            raise ValueError("输入非二进制字符串!")

    dec = 0
    # 计算二进制转十六进制后的位数
    digits = len(data) // 4 + 1

    # 按权相加法BCD转十进制整数
    for bit in range(1, digits + 1):
        dec += (int(data, 2) >> ((digits - bit) * 4) & 0x0F) * 10 ** (
            digits - bit
        )

    return dec

单元测试

def test_dec2bcd() -> None:
    """测试十进制正整数转BCD码"""
    with pytest.raises(TypeError):
        dec2bcd("128", 12)

    with pytest.raises(TypeError):
        dec2bcd(-128, 12)

    with pytest.raises(OverflowError):
        dec2bcd(128, 4)

    assert dec2bcd(128, 12) == "0,0,0,1,0,0,1,0,1,0,0,0"
    assert dec2bcd(2022) == "0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0"
def test_bcd2dec() -> None:
    """测试BCD码转十进制正整数"""
    with pytest.raises(TypeError):
        bcd2dec(10010)

    with pytest.raises(ValueError):
        bcd2dec("s10010")

    assert bcd2dec("1001011110000001") == 9781

如有帮助到各位,请点赞+收藏+关注,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值