python 确保浮点数计算结果正确的方法

因为计算机采用二进制,无法精确的表达浮点数

python 中 用 8字节64位存储空间分配了52位来存储浮点数的有效数字,11位存储指数,1位存储正负号

以下是4字节32为存储的模型

二进制的表示值表达浮点数是(-1)^sign × (1+0.Mantissa) × 2^(Expoment-127)其中127是单精度浮点数的偏移量

而Mantissa最多保留23位,所以在进行累加运算,如果二者指数位相差过大,将会导致数值较小的一方超过23位的尾数全部丢失,造成误差, 52位同理

另一方面,由于有的数据需要保留位数,细微的误差可能导致进位错误

例如:

c = 0.005
a = 0
for i in range(20):
    a += c
    f = float('%.2f' % a)
    if f == a or i % 2 == 1:
        pass
    else:
        print(f, a)

"""
结果
0.01 0.005
0.01 0.015
0.03 0.025
0.04 0.035
0.04 0.045
0.05 0.05499999999999999
0.06 0.06499999999999999
0.07 0.075
0.09 0.085
0.1 0.09500000000000001
"""

可以看到当循环执行第3次的时候,运算结果为0.0149999999999999, 此时真实值应为0.015

保留两位应为0.02, 但是由于小数点后第三位为4, 所以输出结果为0.01, 尽管浮点数产生的误差可以忽略不记,但保留小数点的操作,导致误差被放大到无法忽略的程度,尤其是在财务方面,对数据敏感的行业中,这种误差是不可忽略的

如何确保数据正确呢?

而如果要保证数据的正确性,一般采用两种方法:

方法一: 采用四舍六入五成双的原则

当不需要保留浮点数后面的位数时,可以采用round()

在python3 中,ruand()函数实际上采用的是,值被舍入到接近10的负ndigits次幂的倍数,如果与两个倍数的距离相等,则选择偶数,那么round取整的情况下,就会采用四舍六入五成双的原则

print(round(2.5))
print(round(3.5))
print(round(4.5))
print(round(5.5))
print(round(6.5))

"""
2
4
4
6
6
"""

运行结果永远是偶数

但是在保留小数点的情况下,round并不实行这一原则

print(r
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值