如何在Python中实现任意进制实数的乘法运算?
任意进制实数乘法实现(规避精度丢失)
问题背景
我需要编写一个函数,接收两个任意进制的实数字符串及其进制数,完成乘法运算。现有代码框架如下:
base = int(input()) num1 = input() num2 = input() def multiply(num1: str, num2: str, base: int) -> str: pass
之前尝试将数转换为十进制浮点数后相乘,但会出现精度丢失问题。例如输入:
2 101.1 101.1
预期输出为11110.01,但浮点数转换可能因精度限制导致结果偏差。
解决方案思路
核心思路是避免浮点数转换,直接对字符串形式的进制数进行整数化处理:
- 拆分每个数的整数部分与小数部分,记录小数位数
- 将两个数转换为无小数点的整数字符串,再转成Python大整数(无溢出风险)进行乘法
- 将乘积转回目标进制字符串,根据总小数位数插入小数点
- 处理结果格式:去除前导零、末尾零,以及多余的小数点
实现代码
base = int(input()) num1 = input() num2 = input() def multiply(num1: str, num2: str, base: int) -> str: # 拆分数字的整数和小数部分,同时去除小数末尾的零 def split_num(s): if '.' in s: integer_part, fractional_part = s.split('.', 1) fractional_part = fractional_part.rstrip('0') return integer_part, fractional_part return s, '' int1, frac1 = split_num(num1) int2, frac2 = split_num(num2) # 计算乘积需要保留的总小数位数 total_frac_digits = len(frac1) + len(frac2) # 拼接成无小数点的整数字符串,处理纯小数(如".123")的情况 num1_int_str = int1 + frac1 if int1 else frac1 or '0' num2_int_str = int2 + frac2 if int2 else frac2 or '0' # 转成大整数相乘,Python原生支持任意大小整数,无溢出问题 num1_int = int(num1_int_str, base) num2_int = int(num2_int_str, base) product_int = num1_int * num2_int # 将乘积转回目标进制字符串 if product_int == 0: product_str = '0' else: product_str = '' temp = product_int while temp > 0: digit = temp % base # 处理进制大于10的情况(0-9, A-Z) product_str = (chr(ord('A') + digit - 10) if digit >= 10 else str(digit)) + product_str # 插入小数点并格式化结果 if total_frac_digits == 0: result = product_str else: # 乘积长度不足时补前导零 if len(product_str) <= total_frac_digits: product_str = '0' * (total_frac_digits - len(product_str) + 1) + product_str # 拆分整数和小数部分 result_int = product_str[:-total_frac_digits] result_frac = product_str[-total_frac_digits:].rstrip('0') # 拼接结果,无小数部分则去掉小数点 result = f"{result_int}.{result_frac}" if result_frac else result_int # 去除整数部分前导零,保证结果格式规范 result = result.lstrip('0') or '0' return result print(multiply(num1, num2, base))
测试验证
针对示例输入:
2 101.1 101.1
函数返回11110.01,与预期结果一致。此外还能处理以下边界情况:
- 纯小数相乘:如输入进制10,
.5和.2,输出.1 - 整数与小数相乘:如进制10,
10和0.5,输出5 - 高进制数:如进制16,
A.2和3,输出1E.6
内容的提问来源于stack exchange,提问作者Parzival
相关产品推荐
相关产品推荐

