Python | 乘除计算中的精度问题(乘法&除法)

今天抠一抠细节,记录一下Python在乘除法中的精度问题

1.除法计算

1.1 一般情况下的除法

dived = 20
div = 7
r = dived / div
print(r)

# 运算结果
# result = 2.857142857142857

1.2 获取小数点后100位的精度除法(仅支持整数运算)

根据上图发现,一般情况下计算整数除法,结果本应该是一个无限循环小数,但在小数点第16位时系统默认采用了四舍五入的方式保留了结果,从某种意义上讲,这是一种节约系统资源的做法,但如果想要继续计算解决一些高精度的问题时,需要继续向下做运算,那该如何做呢?

答案思路比较简单,分两步走,先通过整除获得整数,然后通过求余和循环的结合获取小数,之后将两者结合即可。

## 除法精度问题(仅支持整数)
## 思路:分部计算,先计算整数部分,后计算小数部分
dived = 20
div = 7
r = ''
if dived > div:
    t = dived // div;
    r = str(int(t))+'.'
    dived = dived % div
else:
    r = '0.'

for i in range(100):
    dived = dived * 10
    t = dived // div
    r = r + str(int(t))
    dived = dived % div

print(r)


# result
# result = 2.8571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571

通过科学计算器检验结果验证无误。
在这里插入图片描述

1.3 获取小数点后100位的精度除法(支持整数&浮点数)

若要解决浮点数的除法精度问题,思路也不难想,只需要将除数和被除数均化为整数即可,这里的思路是先判断两者右移小数点至整数所需要的最大值(10的multiple次方),之后两数分别乘以此最大值(10的multiple次方)再进行整数运算。

dived = 202  ## 定义被除数
div = 71  ## 定义除数
print("被除数是:", dived)
print("除数是:", div, "\n")

r = ''
## 若存在浮点型,则先转化为整数
if type(dived) == float or type(div) == float:
    print("存在浮点数")
    len_dd = len(str(dived).split(".")[1])
    len_d = len(str(div).split(".")[1])
    print("dived的小数位:", len_dd)
    print("div的小数位:", len_d)
    if len_dd > len_d:
        multiple = len_dd
    else:
        multiple = len_d
    dived = int(10 ** multiple * dived)
    div = int(10 ** multiple * div)
    print("dived化为整数:", dived)
    print("div化为整数:", div)
else:
    print("不存在浮点数")

print("\n正片开始")
## 正片开始
if dived > div:
    t = dived // div;
    r = str(int(t))+'.'
    dived = dived % div
else:
    r = '0.'

for i in range(100):
    dived = dived * 10
    t = dived // div
    r = r + str(int(t))
    dived = dived % div

print(r)

通过比较两次计算结果和科学计算器结果验证无误。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


2.乘法计算

2.1 一般情况下的乘法

一般情况下,两个整数相乘精度没有问题,小数相乘存在精度问题,需要分部解决。

m1 = 0.080189
m2 = 0.0088035
r1 = m1 * m2
print("r1:", r1)

m3 = 0.080189
m4 = 0.00088035
r2 = m3 * m4
print("r2:", r2)

m5 = 801890000000
m6 = 880350000000
r3 = m5 * m6
print("r3:", r3)

在这里插入图片描述

2.1 一般情况下的乘法

在这里插入图片描述

2.2 解决乘法精度问题

def multiple(m1, m2):
    r = ''
    ## 若存在浮点型,则先转化为整数
    if type(m1) == float or type(m2) == float:
        print("存在浮点数")
        len_m1 = len(str(m1).split(".")[1])
        len_m2 = len(str(m2).split(".")[1])
        print("m1的小数位:", len_m1)
        print("m2的小数位:", len_m2)
        
        m1 = int(10 ** len_m1 * m1)
        m2 = int(10 ** len_m2 * m2)
        print("m1化为整数:", m1)
        print("m2化为整数:", m2)
        r = str(m1 * m2)
        print("r:", r)

        l = len_m1 + len_m2
        print("l的总长度:", l)
        if l < len(r):
            r_front = r[:-l]
            r_last = r[-l:]
            print(r_front, "-", r_last)
            r = r_front + "." + r_last
        else:
            r = "0." + (l - len(r)) * "0" + r

        
    else:
        print("不存在浮点数")
        r = m1 * m2

    print("结果为:", r)

m1 = 1.111
m2 = 1.1
r1 = m1 * m2
print("r1:", r1)	# 正常计算
multiple(m1, m2)	# 解决精度问题后的计算

查看结果,r1为一般情况下的计算结果(r1: 1.2221000000000002),解决精度问题后的结果(1.2221)
在这里插入图片描述


尝试一下其他几种情况

m1m2一般情况下的结果r解决精度问题后的结果,multiple(m1,m2)
1.1111.11.22210000000000021.2221
0.0801890.000880357.059438614999999e-050.00007059438615
801898803570594386157059438615
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ParallelLight

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值