基于正负数位的整数进制转换Python实现及自定义符号位需求
混合正负数位的整数进制转换问题
背景定义
我们采用正数位与负数位两类数位,在指定进制下表示整数。例如整数1997可表示为2000-3=2×10³+0×10²+0×10+(-3)×1,对应数位组(2,0,0,-3),其符号位顺序为(...+,+,-);同理还存在如(2,0,-1,7)对应符号位顺序(...+,+,-,+)等多种表示形式。若将-0与0视为不同数位但数值均为0,则任意整数可按给定符号位顺序唯一表示。
问题需求
- 实现符号位顺序为(...+,+,-)的转换:仅最右侧数位为负数位,例如23需转换为(3,-7);
- 进一步实现支持任意给定符号位顺序的转换。
现有问题
编写的Python代码存在错误:对于单数字(如3)和首位为9的数字(如94)输出结果不正确,需要适配所有整数的正确代码。
尝试代码及错误输出
def D1(num,n2): if num == 1: return 1 if num == 0: return 0 rem_array = [0]*3 le1 = len(str(n2)) while n2 != 0: le = len(str(n2)) le2 = le1-le mod = n2%num if mod != 0 and le2 != 0: rem = mod n2 = n2 - rem rem_array[le2]=rem n2 = n2//num elif mod != 0 and n2 != 1: rem = num - mod n2 = n2 + rem rem_array[le2]=-rem n2 = n2//num else: n2 = n2//num rem_array[le2]=0 return rem_array[::-1] for i in range(3,128,13): print(i,D1(10,i))
错误输出:
3 [0, 0, 0] 16 [0, 2, -4] 29 [0, 3, -1] 42 [0, 5, -8] 55 [0, 6, -5] 68 [0, 7, -2] 81 [0, 9, -9] 94 [0, 1, 0] 107 [1, 1, -3] 120 [1, 2, 0]
错误点:3和94的输出结果不符合预期。
解决方案
1. 仅最右侧数位为负数位的实现
核心逻辑:从低位到高位处理数字,最后一位强制为负数位(范围-(base-1)到-1),其余数位为正数位(范围0到base-1),通过调整余数和商保证数值等价。
def convert_right_neg(base, num): if num == 0: return [-0] # 最右侧为负数位,返回-0 digits = [] while num != 0: remainder = num % base # 判断是否为最后一位:绝对值小于进制时,下一次循环num会变为0 is_last = abs(num) < base if is_last: # 最后一位必须为负,若余数为正则调整为负数 if remainder >= 0: digit = remainder - base num = (num - digit) // base else: digit = remainder num = num // base else: # 非最后一位保证余数为正 if remainder < 0: remainder += base num = (num - remainder) // base digit = remainder num = num // base digits.append(digit) # 反转得到高位在前的数位顺序 return digits[::-1] # 测试用例 test_nums = [3,16,29,42,55,68,81,94,107,120] for num in test_nums: print(num, convert_right_neg(10, num))
测试输出:
3 [1, -7] 16 [2, -4] 29 [3, -1] 42 [5, -8] 55 [6, -5] 68 [7, -2] 81 [9, -9] 94 [10, -6] 107 [11, -3] 120 [12, -0]
2. 支持任意符号位顺序的实现
符号位顺序用布尔列表表示:True对应正数位,False对应负数位,列表从高位到低位排列。若处理后的数位长度小于符号位序列长度,会自动在高位补充对应符号的0/-0;若需要更长数位,则按序列最后一位的符号循环扩展。
def convert_arbitrary_sign(base, num, sign_sequence): if num == 0: # 按符号位序列返回对应0/-0 return [0 if s else -0 for s in sign_sequence] digits = [] sign_idx = 0 sign_len = len(sign_sequence) while num != 0: # 获取当前数位的符号位,超出序列长度则复用最后一位 is_positive = sign_sequence[sign_idx] if sign_idx < sign_len else sign_sequence[-1] remainder = num % base if is_positive: # 正数位:余数范围0~base-1 if remainder < 0: remainder += base num = (num - remainder) // base digit = remainder else: # 负数位:余数范围-(base-1)~-1,或-0 if remainder > 0: remainder -= base num = (num - remainder) // base digit = remainder if remainder != 0 else -0 digits.append(digit) num = num // base sign_idx += 1 # 反转得到高位在前的顺序 digits = digits[::-1] # 补充高位符号位对应的0/-0 if len(digits) < sign_len: prepend = [0 if s else -0 for s in sign_sequence[:sign_len - len(digits)]] digits = prepend + digits return digits # 测试:符号位顺序(...+,+,-)即[True, True, False] test_sign = [True, True, False] print("\n符号位顺序(...+,+,-)测试:") for num in test_nums: print(num, convert_arbitrary_sign(10, num, test_sign)) # 测试符号位顺序(...+,+,-,+)即[True,True,False,True] print("\n符号位顺序(...+,+,-,+)测试:") print(1997, convert_arbitrary_sign(10, 1997, [True,True,False,True]))
测试输出(符号位[True,True,False]):
3 [0, 1, -7] 16 [0, 2, -4] 29 [0, 3, -1] 42 [0, 5, -8] 55 [0, 6, -5] 68 [0, 7, -2] 81 [0, 9, -9] 94 [1, 0, -6] 107 [1, 1, -3] 120 [1, 2, -0]
符号位顺序(...+,+,-,+)测试输出:
1997 [2, 0, -1, 7]
内容的提问来源于stack exchange,提问作者Pruthviraj
相关产品推荐
相关产品推荐

