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多线程ctrl+c退出问题解决方案
Oct 23 Python
Python中关于Sequence切片的下标问题详解
Jun 15 Python
Python实现压缩和解压缩ZIP文件的方法分析
Sep 28 Python
python处理csv数据动态显示曲线实例代码
Jan 23 Python
Python实现查看系统启动项功能示例
May 10 Python
Python中矩阵创建和矩阵运算方法
Aug 04 Python
扩展Django admin的list_filter()可使用范围方法
Aug 21 Python
python getpass模块用法及实例详解
Oct 07 Python
pygame实现俄罗斯方块游戏(基础篇3)
Oct 29 Python
8段用于数据清洗Python代码(小结)
Oct 31 Python
pytorch中的weight-initilzation用法
Jun 24 Python
python opencv人脸识别考勤系统的完整源码
Apr 26 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
php session 错误
2009/05/21 PHP
用PHP的超级变量$_POST获取HTML表单(HTML Form) 数据
2011/05/07 PHP
PHP中set_include_path()函数相关用法分析
2016/07/18 PHP
ext实现完整的登录代码
2008/08/08 Javascript
javascript代码加载优化方法
2011/01/30 Javascript
再次分享18个非常棒的jQuery表格插件
2011/04/10 Javascript
javascript继承机制实例详解
2014/11/20 Javascript
JavaScript实现N皇后问题算法谜题解答
2014/12/29 Javascript
浅谈javascript函数式编程
2015/09/06 Javascript
javascript下拉列表中显示树形菜单的实现方法
2015/11/17 Javascript
学习javascript面向对象 理解javascript原型和原型链
2016/01/04 Javascript
jQuery代码性能优化的10种方法
2016/06/21 Javascript
原生js实现ajax方法(超简单)
2016/09/20 Javascript
利用node.js搭建简单web服务器的方法教程
2017/02/20 Javascript
关于javascript获取内联样式与嵌入式样式的实例
2017/06/01 Javascript
vue+node+webpack环境搭建教程
2017/11/05 Javascript
js判断输入框不能为空格或null值的实现方法
2018/03/02 Javascript
Vue常用指令详解分析
2018/08/19 Javascript
python实现rest请求api示例
2014/04/22 Python
python同时给两个收件人发送邮件的方法
2015/04/30 Python
python结合API实现即时天气信息
2016/01/19 Python
用pickle存储Python的原生对象方法
2017/04/28 Python
使用python实现抓取腾讯视频所有电影的爬虫
2019/04/15 Python
python模块hashlib(加密服务)知识点讲解
2019/11/25 Python
python GUI库图形界面开发之PyQt5线程类QThread详细使用方法
2020/02/26 Python
在spyder IPython console中,运行代码加入参数的实例
2020/04/20 Python
详解KMP算法以及python如何实现
2020/09/18 Python
pycharm永久激活超详细教程
2020/10/29 Python
html2canvas生成的图片偏移不完整的解决方法
2020/05/19 HTML / CSS
Foot Locker德国官方网站:美国运动服和鞋类零售商
2018/11/01 全球购物
一道Delphi上机题
2012/06/04 面试题
实践单位评语
2014/04/26 职场文书
2014年学校安全工作总结
2014/11/13 职场文书
2015年财政所工作总结
2015/04/25 职场文书
六一亲子活动感想
2015/08/07 职场文书
JavaScript高级程序设计之变量与作用域
2021/11/17 Javascript