Python逐位逼近法计算根号2时,为何增大迭代次数仍仅得13位精度
精度无法提升的根源
代码运行到第13位小数就卡住,本质是Python内置float类型的精度天花板限制:
- Python默认的
float是符合IEEE 754标准的64位双精度浮点数,依靠二进制结构存储数值,能可靠表示的有效十进制数字仅为15~17位 - 代码中每次拼接数字后都会通过
float(str(x)+str(number))把字符串转成浮点数,当拼接的字符串长度超过float的有效精度上限时,转出来的数值会被自动舍入,和你实际拼接的十进制值已经存在偏差 - 后续基于这个被舍入的近似值计算平方、筛选最大可选数字时,输入值本身就不准,自然无法准确判断更高位的数字该选什么
- 这个精度天花板和循环次数无关,哪怕把循环范围调到大几百次,只要底层还是用
float存数值,结果就永远卡在13位左右的精度水平。
可行的解决方法
方法1:用任意精度整数做运算,彻底规避浮点数误差
Python的整数是无长度限制的任意精度类型,不存在存储溢出、舍入的问题。我们可以把所有小数放大为整数做比较,完全跳过浮点数转换环节:
比如把当前的近似值1.4142表示为整数14142,对应它是原数乘以10^4的结果。每次迭代要拼接的下一位数字k,等价于把整数更新为x_int *10 +k,此时只需要把原不等式做整数等价变形,就能完全精确判断是否满足条件:
# 初始值对应1.4,即14 / 10^1,共1位小数 x_int = 14 decimals = 1 # 这里的循环次数就是要计算的小数位数,想算多少就设多少 for _ in range(50): # 从9倒序找最大的满足条件的数字,比遍历收集候选效率更高 for k in range(9, -1, -1): new_int = x_int * 10 + k # 原判断式:(new_int / 10^(decimals+1))² < 2 # 两边同乘10^(2*(decimals+1)),得到无浮点的整数比较式 if new_int * new_int < 2 * (10 ** (decimals + 1)) ** 2: x_int = new_int decimals += 1 break # 把整数还原为带小数点的字符串输出 result = f"{str(x_int)[0]}.{str(x_int)[1:]}" print(result)
这种方法算到几百、上千位的精度都不会出现误差。
方法2:使用标准库decimal的任意精度十进制数
如果不想手写整数转换逻辑,可以直接用Python自带的decimal模块,它支持自定义精度的十进制浮点数。只要提前把全局精度设置成你需要的位数,全程用Decimal类型替代普通float做运算,就能避免精度被锁死的问题。
注意初始化Decimal值时,要直接用数字字符串初始化,不要先把字符串转成普通float再转Decimal,否则还是会继承普通float的精度误差。
内容的提问来源于stack exchange,提问作者HAECHANG YUN
相关产品推荐
相关产品推荐

