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

通过科学计算器检验结果验证无误。
Python | 乘除计算中的精度问题(乘法&除法)

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)

通过比较两次计算结果和科学计算器结果验证无误。
Python | 乘除计算中的精度问题(乘法&除法)
Python | 乘除计算中的精度问题(乘法&除法)
Python | 乘除计算中的精度问题(乘法&除法)


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)

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

2.1 一般情况下的乘法

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

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)
Python | 乘除计算中的精度问题(乘法&除法)


尝试一下其他几种情况

m1 m2 一般情况下的结果r 解决精度问题后的结果,multiple(m1,m2)
1.111 1.1 1.2221000000000002 1.2221
0.080189 0.00088035 7.059438614999999e-05 0.00007059438615
80189 88035 7059438615 7059438615
上一篇:专业的矢量绘图软件:ai2021中文版(支持m1)


下一篇:inherit 关键字使得元素获取其父元素的计算值