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 8∗160+2∗161+1∗162=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 8∗100+2∗101+1∗102=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
如有帮助到各位,请点赞+收藏+关注,谢谢