二进制浮点数转100+位小数十进制数及素数常量精度问题咨询
二进制浮点数转100+位小数十进制数及素数常量精度问题咨询
我来帮你排查这个精度受限的问题——你明明设置了getcontext().prec=100,但输出却只能到51位小数,核心问题出在中间步骤用了普通浮点除法,提前损失了精度。
先看你代码里的关键计算行:
base10 = Decimal(int(joinsplit, base=base) / divisor)
这里你先把二进制字符串转成整数,然后用Python默认的/做除法——但普通的Python float是64位的,最多只能保留约15-17位十进制有效数字,这一步直接把后面的精度都丢了。等你再把这个不精确的float转成Decimal时,哪怕设置了100位精度,也已经找不回之前丢失的部分了。
解决方法:全程用Decimal运算,避开普通float
只需要把除法运算改成纯Decimal操作,就能保住你要的100位精度:
修改后的完整代码如下:
from decimal import * getcontext().prec = 100 base = 2 s = "0.0110101000101000101000100000101000001000101000100000100000101000001000101000001000100000100000001000101000101000100000000000001000100000101000000000101000001000001000100000100000101000000000101000101000000000001000000000001000101000100000101000000000100000100000100000101000001000101000000000100000000000001000101000100000000000001000001000000000101000100000100000001000001000001000100000100000001000100000001000000000101000000000101000001000100000100000001000101000100000000000100000001000100000001000100000100000000000101000000000000000001000001000000000100000100000101000001000000000100000100000101000001000001000101000000000001000000000101000100000100000101000000000001000100000100000001000000000100000001000000000100000001000001000001000100000001000001000100000001000100000000000001000000000100000000000101000000000101000101000000000100000000000001000101000100000000000001000101000100000000000000000001000100000001000000000100000001000100000100000100000000000001000100000100000100000001000001000000000001000100000101000" split = s.split(".") joinsplit = "".join(split) position = len(split[1]) if len(split) > 1 else 0 # 改为纯Decimal运算,避免float精度损失 divisor = Decimal(base) ** position base10 = Decimal(int(joinsplit, base=base)) / divisor print(base10)
为什么这样修改有效?
- 直接将二进制转成的整数转为Decimal类型,全程用你设置的100位精度进行运算
- 用Decimal的幂运算构建divisor,避免了大整数转float的精度损失
- 除法运算完全在Decimal的高精度环境下执行,保留了所有有效数字
这样修改后,你就能得到完整的100位十进制精度的素数常量输出了。
备注:内容来源于stack exchange,提问作者D W
相关产品推荐
相关产品推荐

