Python如何执行精确的浮点数运算


Posted in Python onJuly 31, 2020

问题

你需要对浮点数执行精确的计算操作,并且不希望有任何小误差的出现。

解决方案

浮点数的一个普遍问题是它们并不能精确的表示十进制数。 并且,即使是最简单的数学运算也会产生小的误差,比如:

>>> a = 4.2
>>> b = 2.1
>>> a + b
6.300000000000001
>>> (a + b) == 6.3
False
>>>

这些错误是由底层CPU和IEEE 754标准通过自己的浮点单位去执行算术时的特征。 由于Python的浮点数据类型使用底层表示存储数据,因此你没办法去避免这样的误差。

如果你想更加精确(并能容忍一定的性能损耗),你可以使用 decimal 模块:

>>> from decimal import Decimal
>>> a = Decimal('4.2')
>>> b = Decimal('2.1')
>>> a + b
Decimal('6.3')
>>> print(a + b)
6.3
>>> (a + b) == Decimal('6.3')
True

初看起来,上面的代码好像有点奇怪,比如我们用字符串来表示数字。 然而, Decimal 对象会像普通浮点数一样的工作(支持所有的常用数学运算)。 如果你打印它们或者在字符串格式化函数中使用它们,看起来跟普通数字没什么两样。

decimal 模块的一个主要特征是允许你控制计算的每一方面,包括数字位数和四舍五入运算。 为了这样做,你先得创建一个本地上下文并更改它的设置,比如:

>>> from decimal import localcontext
>>> a = Decimal('1.3')
>>> b = Decimal('1.7')
>>> print(a / b)
0.7647058823529411764705882353
>>> with localcontext() as ctx:
...   ctx.prec = 3
...   print(a / b)
...
0.765
>>> with localcontext() as ctx:
...   ctx.prec = 50
...   print(a / b)
...
0.76470588235294117647058823529411764705882352941176
>>>

讨论

decimal 模块实现了IBM的”通用小数运算规范”。不用说,有很多的配置选项这本书没有提到。

Python新手会倾向于使用 decimal 模块来处理浮点数的精确运算。 然而,先理解你的应用程序目的是非常重要的。 如果你是在做科学计算或工程领域的计算、电脑绘图,或者是科学领域的大多数运算, 那么使用普通的浮点类型是比较普遍的做法。 其中一个原因是,在真实世界中很少会要求精确到普通浮点数能提供的17位精度。 因此,计算过程中的那么一点点的误差是被允许的。 第二点就是,原生的浮点数计算要快的多-有时候你在执行大量运算的时候速度也是非常重要的。

即便如此,你却不能完全忽略误差。数学家花了大量时间去研究各类算法,有些处理误差会比其他方法更好。 你也得注意下减法删除以及大数和小数的加分运算所带来的影响。比如:

>>> nums = [1.23e+18, 1, -1.23e+18]
>>> sum(nums) # Notice how 1 disappears
0.0
>>>

上面的错误可以利用 math.fsum() 所提供的更精确计算能力来解决:

>>> import math
>>> math.fsum(nums)
1.0
>>>

然而,对于其他的算法,你应该仔细研究它并理解它的误差产生来源。

总的来说, decimal 模块主要用在涉及到金融的领域。 在这类程序中,哪怕是一点小小的误差在计算过程中蔓延都是不允许的。 因此, decimal 模块为解决这类问题提供了方法。 当Python和数据库打交道的时候也通常会遇到 Decimal 对象,并且,通常也是在处理金融数据的时候。

以上就是Python如何执行精确的浮点数运算的详细内容,更多关于Python执行精确的浮点数运算的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python通过exifread模块获得图片exif信息的方法
Mar 16 Python
python中查看变量内存地址的方法
May 05 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
Dec 25 Python
Python实现微信自动好友验证,自动回复,发送群聊链接方法
Feb 21 Python
Python使用itchat模块实现简单的微信控制电脑功能示例
Aug 26 Python
windows下Pycharm安装opencv的多种方法
Mar 05 Python
python函数map()和partial()的知识点总结
May 26 Python
tensorflow之读取jpg图像长和宽实例
Jun 18 Python
Python学习工具jupyter notebook安装及用法解析
Oct 23 Python
Pycharm在指定目录下生成文件和删除文件的实现
Dec 28 Python
基于python制作简易版学生信息管理系统
Apr 20 Python
Anaconda配置各版本Pytorch的实现
Aug 07 Python
Python使用shutil模块实现文件拷贝
Jul 31 #Python
Python基于pyjnius库实现访问java类
Jul 31 #Python
Python如何将字符串转换为日期
Jul 31 #Python
Python在字符串中处理html和xml的方法
Jul 31 #Python
python中selenium库的基本使用详解
Jul 31 #Python
Python过滤序列元素的方法
Jul 31 #Python
python中的django是做什么的
Jul 31 #Python
You might like
CI框架中zip类应用示例
2014/06/17 PHP
JavaScript Event学习第十一章 按键的检测
2010/02/10 Javascript
Get中文乱码IE浏览器Get中文乱码解决方案
2013/12/26 Javascript
jQuery 取值、赋值的基本方法整理
2014/03/31 Javascript
jQuery的缓存机制浅析
2014/06/07 Javascript
Javascript中3种实现继承的方法和代码实例
2014/08/12 Javascript
indexOf 和 lastIndexOf 使用示例介绍
2014/09/02 Javascript
jQuery+Ajax实现无刷新分页
2015/10/30 Javascript
jQuery原理系列-css选择器的简单实现
2016/06/07 Javascript
AngularJS 输入验证详解及实例代码
2016/07/28 Javascript
酷! 不同风格页面布局幻灯片特效js实现
2021/02/19 Javascript
浅谈Angular的$q, defer, promise
2016/12/20 Javascript
浅谈angularjs $http提交数据探索
2017/01/20 Javascript
在Vue项目中引入腾讯验证码服务的教程
2018/04/03 Javascript
详解vue 单页应用(spa)前端路由实现原理
2018/04/04 Javascript
详解vue表单——小白速看
2018/04/08 Javascript
微信小程序常见页面跳转操作简单示例
2019/05/01 Javascript
微信小程序实现锚点功能
2019/11/20 Javascript
python实现apahce网站日志分析示例
2014/04/02 Python
用Python操作字符串之rindex()方法的使用
2015/05/19 Python
python opencv检测目标颜色的实例讲解
2018/04/02 Python
解决pandas中读取中文名称的csv文件报错的问题
2018/07/04 Python
python自动化生成IOS的图标
2018/11/13 Python
python的内存管理和垃圾回收机制详解
2019/05/18 Python
python super的使用方法及实例详解
2019/09/25 Python
pycharm新建Vue项目的方法步骤(图文)
2020/03/04 Python
python中使用asyncio实现异步IO实例分析
2021/02/26 Python
Jo Malone美国官网:祖玛珑香水
2017/03/27 全球购物
客户服务经理岗位职责
2014/01/29 职场文书
高中生班主任评语
2014/04/25 职场文书
幼儿教师自我剖析材料
2014/09/29 职场文书
热情服务标语
2014/10/07 职场文书
陕西导游词
2015/02/04 职场文书
四大名著读书笔记
2015/06/25 职场文书
公司财务制度:成本管理控制制度模板
2019/11/19 职场文书
python3实现常见的排序算法(示例代码)
2021/07/04 Python