0
点赞
收藏
分享

微信扫一扫

python运算float浮点数精度丢失问题及解决方案


问题复现

3.8+3.9
7.699999999999999

3.8*3.9
14.819999999999999


精度丢失原因

这个是计算机本身的问题,不止是python会有这个问题,所有语言都会有这个问题,遵循​​ IEEE 754​​ 规范,采用双精度存储(double precision),占用64bit
浮点数在计算机中实际是以二进制保存的,有些数不精确。
比如说: 0.1是十进制,转化为二进制后它是个无限循环的数:
0.00011001100110011001100110011001100110011001100110011001100
而python是以双精度(64)位来保存浮点数,多余的位会被截掉,所以看到的是0.1,但在电脑上实际保存的已不是精确的0.1,参与运算后,也就有可能点误差。

解决方案


方案1:先将浮点数放大倍数到整数,再进行运算,最后将结果缩小倍数。

直接上代码:

def ymul(*numbers):
"""
乘积
:param numbers: eg: [1.2, 2.21, 3.141]
:return:
"""
nums = [str(n).partition(".") for n in numbers]
product = 1
place = 0
for n in nums:
product *= int(f"{n[0]}{n[2]}")
place += len(n[2])
r = product / 10 ** place
return r


def ysum(*numbers):
"""
相加, 和
:param numbers: eg: [1.2, 2.21, 3.141]
:return:
"""
nums = [str(n).partition(".") for n in numbers]
max_place = max(len(n[2].strip("-")) for n in nums) # 最大小数位
product = sum(int(f"{n[0]}{n[2].ljust(max_place, '0')}") for n in nums)
r = product / 10 ** max_place
return r

if __name__ == '__main__':
print(ymul(3.8, 3.9))
print(ysum(3.8, 3.9))

运行结果如下:

14.82
7.7

不导入任何包,完美解决精度丢失的问题!!!

方案2: 使用 decimal 包解决

from decimal import Decimal

Decimal("3.8") + Decimal("3.9")
Decimal("3.8") * Decimal("3.9")

运行结果如下:

Decimal('7.7')
Decimal('14.82')

解决!!!

举报

相关推荐

01-浮点数精度问题bug

0 条评论