奇怪的现象

前几天跟同事聊起来,在计算机内部float比较是很坑爹的事情。比方说,0.1+0.2得到的结果竟然不是0.3?

>>> 0.1+0.2
0.30000000000000004

为什么会出现如此傻的结果呢?

这篇文章做了详细的解释,简单的来说就是计算机里面的数字是由二进制保存的,在计算机内部有些数字不能准确的保存,于是就保存一个最靠近的数字。

在十进制中也会存在这样的问题,数字不能准确地表示像1/3这样的数字,所以你必须舍入到0.33之类的东西 - 你不要指望0.33 + 0.33 + 0.33加起来就是1。

因此我们在比较两个float是否相等时,不能仅仅依靠 == 来进行判断,而是当他们两者的差小于一个我们可以容忍的小值时,就可以认为他们就是相等的。

Python中是如何解决的?

各种语言中都有类似的处理方式,python中是这样处理的?

StackOverFlow有类似的问题: what-is-the-best-way-to-compare-floats-for-almost-equality-in-python

简单粗暴的判断方法

return abs(f1 - f2) <= allowed_error

python3.5之后,PEP485提案中已给出了解决方案。

使用math.isclose方法,传入需要比较的两个数和可以接受的精度差值即可。

PEP 485: A function for testing approximate equality

PEP 485 adds the math.isclose() and cmath.isclose() functions which tell whether two values are approximately equal or “close” to each other. Whether or not two values are considered close is determined according to given absolute and relative tolerances. Relative tolerance is the maximum allowed difference between isclose arguments, relative to the larger absolute value:

math.isclose 使用方法

>>> import math
>>> a = 5.0
>>> b = 4.99998
>>> math.isclose(a, b, rel_tol=1e-5)
True
>>> math.isclose(a, b, rel_tol=1e-6)
False
It is also possible to compare two values using absolute tolerance,
which must be a non-negative value: >>> import math
>>> a = 5.0
>>> b = 4.99998
>>> math.isclose(a, b, abs_tol=0.00003)
True
>>> math.isclose(a, b, abs_tol=0.00001)
False

在python中如何比较两个float类型的数据是否相等的更多相关文章

  1. SQL中的float类型的数据

    问题1.  如何在SQL中默认的使用float类型的数据 SQL中想要通过计算的方式最快的得到一个float类型的数据,只需要运算的其中一个值后面加上小数点就ok. 比如 :9/2=4 但是 :9/2 ...

  2. python中是否有单独的字符类型,通过下标的方式表示字符串中的字符

    说明: 在python中,没有单独的字符类型,一个字符呢就是一个大小为1的字符串. 并且可以通过下标的方式,表示字符串中的字符. 操作过程: 1.通过[ ]的方式表示字符串中的第几个字符 >&g ...

  3. 两个int类型的数据相加,有可能会出现超出int的表示范围。

    两个int类型的数据相加,有可能会出现超出int的表示范围. /* 移位运算符: <<(左移) 规律:一个操作数进行左移运算的时候,结果就是等于操作数乘以2的n次方,n就是左移 的位数. ...

  4. 海选与包装,Python中常用的两个高阶函数(讲义)

    一.filter(function, iterable) - 过滤("海选") # 判断落在第一象限的点[(x1, y1), (x2, y2)...] points = [(-1, ...

  5. Python中请使用isinstance()判断变量类型

    一.isinstance() 在Python中可以使用type()与isinstance()这两个函数判断对象类型,而isinstance()函数的使用上比type更加方便. # coding=utf ...

  6. Python中从SQL型数据库读写dataframe型数据

    Python的pandas包对表格化的数据处理能力很强,而SQL数据库的数据就是以表格的形式储存,因此经常将sql数据库里的数据直接读取为dataframe,分析操作以后再将dataframe存到sq ...

  7. Python 中 如何将两个列表元素一一对应成字典

    使用python的 zip函数 和强大的集合操作可以方便的将两个list元素一一对应转换为dict,如下示例代码: names = ['n1','n2','n3'] values = [1,2,3] ...

  8. python中的字典两种遍历方式

    dic = {"k1":"v1", "k2":"v2"} for k in dic: print(dic[K]) for ...

  9. python中如何将两个list合并成一个list,不用for语句

    1, add 2, 用list的extend方法,L1.extend(L2),该方法将参数L2的全部元素添加到L1的尾部,例如: 3, 用切片(slice)操作,L1[len(L1):len(L1)] ...

随机推荐

  1. 循环语句:LOOP,WHILE和数字式循环

    一 简单循环 1 语法: LOOP      要执行的语句;      EXIT WHEN <条件语句> --条件满足,退出循环语句  END LOOP; 2 例子: DECLARE    ...

  2. 没有CTO的Netflix有哪些值得我们学习的工程文化?

    作者介绍: 杨波,拍拍贷基础框架研发总监.具有超过 10 年的互联网分布式系统研发和架构经验,曾先后就职于:eBay 中国研发中心(eBay CDC),任资深研发工程师,参与亿贝开放 API 平台研发 ...

  3. Logrotate实现Catalina.out日志每俩小时切割

    一.Logrotate工具介绍 Logrotate是一个日志文件管理工具,它是Linux默认自带的一个日志切割工具.用来把旧文件轮转.压缩.删除,并且创建新的日志文件.我们可以根据日志文件的大小.天数 ...

  4. mysql,oracle表数据相互导入

    mysql导入oracle: 例如mysql中有ts_user_info表,现在要导入到oracle中的user_info表 1:导出mysql表数据到data.txt文件 mysql> sel ...

  5. laravel cache get 是如何调用的?

    本文使用版本为laravel5.5 cache get public function cache() { $c=\Cache::get('app'); if(!$c) { \Cache::put(' ...

  6. JAVA实现RSA加密,非对称加密算法

    RSA.java package org.icesnow.jeasywx.util.security; import java.security.Key; import java.security.K ...

  7. JavaSE 第二次学习随笔(一)

    Java是一种区分大小写的强类型准动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化,类型的检查是在运行时做的,优点为方便阅读,清晰明了,缺点 ...

  8. 多线程之ReadWriteLock模拟缓存(九)

    错误案例1: package com.net.thread.lock; import java.util.HashMap; import java.util.Map; import java.util ...

  9. photoshop入门笔记1:PS的快捷键

    PS部分快捷键: 1.魔棒的作用:比较快捷的抠图工具,对于一些分界线比较明显的图像,通过魔棒工具可以很快速的将图像抠出,魔棒的作用是可以知道你点击的那个地方的颜色,并自动获取附近区域相同的颜色,使它们 ...

  10. Git-Git分支

    代码管理之殇 分支是代码管理的利器.如果没有有效的分支管理,代码管理就适应不了复杂的开发过程和项目的需要.在实际的项目实践中,单一分支的单线开发模式还远远不够,因为: 成功的软件项目大多要经过多个开发 ...