python中实现精确的浮点数运算详解


Posted in Python onNovember 02, 2017

为什么说浮点数缺乏精确性?

在开始本文之前,让我们先来谈谈浮点数为什么缺乏精确性的问题,其实这不是Python的问题,而是实数的无限精度跟计算机的有限内存之间的矛盾。

举个例子,假如说我只能使用整数(即只精确到个位,计算机内的浮点数也只有有限精度,以C语言中的双精度浮点数double为例,精度为52个二进制位),要表示任意实数(无限精度)的时候我就只能通过舍入(rounding)来近似表示。

比如1.2我会表示成1,2.4表示成2,3.6表示成4.

所以呢?

在算1.2 - 1.2的时候,由于计算机表示的问题,我算的实际上是1 - 1,结果是0,碰巧蒙对了;

在算1.2 + 1.2 - 2.4的时候,由于计算机表示的问题,我算的实际上是1 + 1 - 2,结果是0,再次蒙对了;

但是在算1.2 + 1.2 + 1.2 - 3.6的时候,由于计算机表示的问题,我算的实际上是1 + 1 + 1 - 4,结果是-1,运气没那么好啦!

这里的1.2, 2.4, 3.6就相当于你问题里的0.1, 0.2和0.3,1, 2, 4则是真正在计算机内部进行运算的数值,我说清楚了吗?

其他请看IEEE 754浮点数标准,比如CSAPP第二章啥的(虽然估计你没兴趣看)。

另:不仅仅是浮点数的在计算机内部的表示有误差,运算本身也可能会有误差。比如整数2可以在计算机内准确表示,但是要算根号2就有误差了;再比如两个浮点数相除,本来两个数都是精确表示的,但除的结果精度却超出了计算机内实数的表示范围,然后就有误差了。

好了,下面话不多说了,开始本文的正文:

起步

浮点数的一个普遍的问题是它们不能精确的表示十进制数。

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

这是由于底层 CPU 和IEEE 754 标准通过自己的浮点单位去执行算术时的特征。看似有穷的小数, 在计算机的二进制表示里却是无穷的。

一般情况下,这一点点的小误差是允许存在的。如果不能容忍这种误差(比如金融领域),那么就要考虑用一些途径来解决这个问题了。

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 Decimal, 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 的高精度数字自然也就用字符串来做展示和中转。

总结

总的来说,当涉及金融领域时,哪怕是一点小小的误差在计算过程中都是不允许的。因此 decimal 模块为解决这类问题提供了方法。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python中定义结构体的方法
Mar 04 Python
python通过ElementTree操作XML获取结点读取属性美化XML
Dec 02 Python
Python实现扫描局域网活动ip(扫描在线电脑)
Apr 28 Python
梯度下降法介绍及利用Python实现的方法示例
Jul 12 Python
linecache模块加载和缓存文件内容详解
Jan 11 Python
简单了解Django ContentType内置组件
Jul 23 Python
Pandas之groupby( )用法笔记小结
Jul 23 Python
Python3 把一个列表按指定数目分成多个列表的方式
Dec 25 Python
Python可以实现栈的结构吗
May 27 Python
python利用pytesseract 实现本地识别图片文字
Dec 14 Python
python之django路由和视图案例教程
Jul 26 Python
python中对列表的删除和添加方法详解
Feb 24 Python
利用Python-iGraph如何绘制贴吧/微博的好友关系图详解
Nov 02 #Python
python3.0 模拟用户登录,三次错误锁定的实例
Nov 02 #Python
Python安装Numpy和matplotlib的方法(推荐)
Nov 02 #Python
Python 多进程并发操作中进程池Pool的实例
Nov 01 #Python
python 3.0 模拟用户登录功能并实现三次错误锁定
Nov 01 #Python
python 简单搭建阻塞式单进程,多进程,多线程服务的实例
Nov 01 #Python
Python编程实现双链表,栈,队列及二叉树的方法示例
Nov 01 #Python
You might like
定制404错误页面,并发信给管理员的程序
2006/10/09 PHP
PHP读MYSQL中文乱码的解决方法
2006/12/17 PHP
ThinkPHP单字母函数(快捷方法)使用总结
2014/07/23 PHP
js传值 判断
2006/10/26 Javascript
简明json介绍
2008/09/28 Javascript
javascript contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
2010/02/04 Javascript
javascript document.compatMode兼容性
2010/02/23 Javascript
js onkeypress与onkeydown 事件区别详细说明
2012/12/13 Javascript
关于JQuery($.load)事件的用法和分析
2013/04/09 Javascript
javascript截取字符串(通过substring实现并支持中英文混合)
2013/06/24 Javascript
JavaScript实现QueryString获取GET参数的方法
2013/07/02 Javascript
jQuery如何取id有.的值一般的方法是取不到的
2014/04/18 Javascript
node.js中的fs.createWriteStream方法使用说明
2014/12/17 Javascript
Javascript闭包(Closure)详解
2015/05/05 Javascript
jQuery实现判断滚动条到底部
2015/06/23 Javascript
浅谈JS函数节流防抖
2017/10/18 Javascript
JS判断数组里是否有重复元素的方法小结
2019/05/21 Javascript
原生JS与CSS实现软件卸载对话框功能
2019/12/05 Javascript
JS数组转字符串实现方法解析
2020/09/04 Javascript
python爬虫实现教程转换成 PDF 电子书
2017/02/19 Python
纯python进行矩阵的相乘运算的方法示例
2019/07/17 Python
python GUI图形化编程wxpython的使用
2019/07/19 Python
Python使用Turtle库绘制一棵西兰花
2019/11/23 Python
python读写Excel表格的实例代码(简单实用)
2019/12/19 Python
python redis存入字典序列化存储教程
2020/07/16 Python
德国网上药房:Apotal
2017/04/04 全球购物
汉森批发:Hansen Wholesale
2018/05/24 全球购物
LINUX下线程,GDI类的解释
2012/04/17 面试题
战友聚会邀请函
2014/01/18 职场文书
优秀导游先进事迹材料
2014/01/25 职场文书
人资专员岗位职责
2014/04/04 职场文书
韩语专业职业生涯规划范文:成功之路就在我们脚下
2014/09/11 职场文书
企业工会工作总结2015
2015/05/13 职场文书
运动会通讯稿300字
2015/07/20 职场文书
python非标准时间的转换
2021/07/25 Python
Docker部署Mysql8的实现步骤
2022/07/07 Servers