python布尔运算可以比较浮点数吗_Python3 基础之:令人困惑的浮点数运算
0、1 + 0.68 不等于 1.68
我们先来看一行简单的代码:
a = 1 + 0.68
b = 1.68
is_equal = (a == b)
print("{}=={}is{}".format(a, b, is_equal))
逻辑上,上面的代码的输出结果应该为:
1.68 == 1.68 is True
然而,实际上真正的输出结果是:
1.6800000000000002 == 1.68 is False
你是否在实际的开发过程中遇到类似的问题,并因为付出了大量的DEBUG时间,最终才发现这么一个违反直觉的现象。
我们可以信手就举几个违反直觉的、看似相等,实则不想等的例子:
0.1 + 0.1 + 0.1 == 0.3 # False
0.99 * 3 == 2.97 # False
事实上,这个问题是所有编程语言都会遇到的问题,它都不能算是一个BUG,而算是一个非常正常的现象。
那么问题来了:我们怎么才能比较两个浮点数是否想等呢?
我们将在本文的最后回答这个问题。
1、浮点数的精度问题
我们都知道,计算机是以二进制的形式保存数据的。无论是整数还是浮点数,都不例外。举个例子,十进制浮点数字0.125的二进制表达式为:
0.001
# 0.125 = 0*2 + 0/2 + 0/4 + 1/8
# 0. 0 0 1
如果你看不懂上面的转换,你应该先了解一下十进制浮点数与二进制浮点数之间的转换,再来阅读本文。本文是在假设你已经了解这个规则的基础上编写的。
我们知道,当我们用十进制小数表达1/3的时候,它是一个无穷循环的小数。
# 1/3 的十进制小数表达:
0.33333333333333333333333333...
我们无法穷举所有的3,所以没有办法通过穷举再准确地表达1/3,而只是通过尽量多的穷举,去更接近的表达(近似表达)。
同样的,计算在表达一个数值(二进制)的时候,也是通过只能通过穷举一定的位数,来达到表达一个浮点数的效果。当计算机表述一个64位的浮点数时,一般是用10位来表达指数,用54位来表达精度。所以,当一个小数的位数超过54的时候,计算机就无法精准的表达,而只能取其近似值。
举个例子,十进制数0.1的二进制表达式为:
0.0001100110011001100110011001100110011001100110011...
如果是64位的浮点数,那么计算机只能取小数点后54位的精度。
我们先来看一段代码:
a = 0.1
print(a)
print("{:.20f}".format(a))
其它结果为:
0.1
0.10000000000000000555
第一个打印的结果,看似正确,事实上只是一个表象;这是计算机为我们做了尽量接近原数值的推算和展示(这个超过本文的讨论范围,不深入讨论)。
当我们把精度取到20位的时候(第二行结果),我们就会出现计算机在存储0.1的这数值的时候,其实并不是准确的存储了0.1,而是存储了一个近似值。正如我们前面所提到的,用有限位的二进值小数,并没有办法精确的表达十进制小数0.1。
2、如何比较两个浮点数是否相等
很遗憾,我们的答案是:不能。
这是一个非常重要的计算机常识。
如果你尝试通过==来判定两个浮点数是否相等,你有可能就陷入了第一节所讨论的陷阱。所以,除非你非常明确自己的意图,否则你千万不要这么做。
但是判定两个浮点数是否相等,却是一个非常普通而常见的操作,我们应该怎么做呢?
答案是:取近似值。
当我们直接用==判定两个64位浮点数(注意我们这里提到了位数)是否相等时,事实上是对比两个浮点数在54位的精度上(与小数点后54不是同一个概念)的近似值是否相等。
同理,当你判定两个浮点数是否相等时,你应该取一个适当的精度。而这个精度应该根据你实际功能的需要决定。
回到我们第0节所提到的1.68的问题,当我们取小数点后15位以内时,这两个数值就可以判定为近似相等。
a = 1.68
b = 1 + 0.68
print("a={:.20}".format(a))
print("b={:.20}".format(b))
eps = 0.00001
if abs(a - b) < eps:
print("a == b")
上面代码的打印结果为:
a=1.6799999999999999378
b=1.6800000000000001599
a == b
浮点数计算一个很专业和复杂的问题,我这里只是抛砖引玉,简单地介绍,如果你感兴趣,可以专门去了解一下。这里有几个链接仅各位参考一下:https://docs.python.org/3/tutorial/floatingpoint.htmldocs.python.orgBinary numbers – floating point conversionblog.penjee.com
python布尔运算可以比较浮点数吗_Python3 基础之:令人困惑的浮点数运算相关推荐
- python取的键不存在_Python3基础 dict get 在查询不存在的键时,返回指定的内容
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda : 4.5.11 typesetting : Markdown ...
- python读取txt文件每一行_Python3基础 file for+list 读取txt文本 并 一行一行的输出(低效率)...
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda : 4.5.11 typesetting : Markdown ...
- python 写文件 不存在创建_Python3基础 文件write 与 open(w) 对一个不存在的txt进行创建与写入...
镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体. ------------------------------------- ...
- python中not加变量是_Python3基础 in 与 not in 判断一个变量是否在列表中存在
镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体. ------------------------------------- ...
- python类的定义和使用_Python3基础之python 之 面向对象基础(定义类、创|python基础教程|python入门|python教程...
第七章面向对象 1.面向过程编程核心是"过程"二字,过程指的是解决问题的步骤,即先干什么再干什么基于该思想编写程序就好比在编写一条流水线,是一种机械式的思维方式 优点:复杂的问题流 ...
- 如何找到python廖雪峰基础_python3 基础 廖雪峰教程笔记-1
廖雪峰教程文档:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143252 ...
- python怎么输出浮点数_python 零基础入门教程第 2 章:基本数据类型 (一)
一.什么是数据类型 编程语言通过一些复杂的计算机物理底层机制,创造不同类型的数据,用来表示现实世界中的不同信息,以便于计算机更好的存储和计算. 每种编程语言都会有一些基本的数据类型用来表示现实世界中的 ...
- python编程中常用的12种基础知识总结
python编程中常用的12种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序.去重,字典排序,字典.列表.字符串互转,时间对象操作,命令行参数解析(getopt),print 格式化输出,进 ...
- Python 数据分析与展示笔记1 -- Numpy 基础
Python 数据分析与展示笔记1 – NumPy 基础 Python 数据分析与展示系列笔记是笔者学习.实践Python 数据分析与展示的相关笔记 课程链接: Python 数据分析与展示 参考文档 ...
最新文章
- java异常处理试题答案_JAVA异常处理试题及答案
- MATLAB优化问题
- 数据结构与算法之“之”字型打印矩阵和矩阵中找数
- me shy是什么歌 抖音make_内含活动福利 | 小红书、抖音爆赞的高颜值的北欧家居神店开到卜蜂中心啦!...
- github gists 101使代码共享漂亮
- 乘法原理的例题和答案_吃透高考数学17个必考题型,基础再差也能考130!(内附解题技巧+例题解析)...
- [算法 笔记]2014年去哪儿网 开发笔试(续)第一题BUG修正
- 华为云整合三朵云能力,第二阶段决战大政企战场
- 蔡高厅老师 - 高等数学阅读笔记 - 02 - 极限(06 、07、08、09、10、11、12)
- ArrayList和LinkedList的插入删除性能差距到底有多大
- SQL http://www.myfeng.cn/?T3009
- 如何深入浅出地讲解麦克斯韦方程组
- java 链表插入排序,insertion Sort List (链表的插入排序) leecode java
- ios平台实现视频H264硬编码及软编码(附完整demo)
- 拍拍抢拍精灵v2.1秒杀器所有源代码【开源】
- js 精确判断对象的类型
- Android 开源项目分类汇总(很全)
- 一种高性能无锁队列设计
- 计算机开机桌面空白,电脑开机桌面一片空白是怎么回事?
- html5 2019新年祝福页面,2019新年创意祝福语 绝对让你的心意顺利送达