double类型(浮点数)是否相等的判断方法

2023-10-27

浮点数不精确

计算机内部无法用二进制的小数来精确的表达。

public class Tesz {
    public static void main(String[] args) {

        double a = 0.1;
        float c = 0.1f;
        System.out.println(a==c);//输出false
    }
}
  • 如果运算符任意一方的类型为double,则另一方会转换为double
  • 否则,如果运算符任意一方的类型为float,则另一方会转换为float
  • 否则,如果运算符任意一方的类型为long,则另一方会转换为long
  • 否则,两边都会转换为int

根据IEEE 754,单精度的float是32位,双精度的double为64位

第一部分(s)为符号位,第二部分(exponent)为指数位,第三部分(mantissa)为基数部分。 这是科学计数法的二进制表示。

  •  比如像3.1415926.。。。  或者无限无限循环小数,就会将不能标识的部分舍掉。
  • 二进制无法精确表示浮点数

二进制为什么无法精确表示浮点数

单精度浮点数0.1表示成二进制

System.out.println(Integer.toBinaryString(Float.floatToIntBits(0.1f)));  

结果是:111101110011001100110011001101
双精度的浮点数0.1的二进制

System.out.println(Long.toBinaryString(Double.doubleToLongBits(0.1d)));  

结果是:11111110111001100110011001100110011001100110011001100110011010
float转换后的double的值已经和直接赋值的double的值比较

System.out.println(Long.toBinaryString(Double.doubleToLongBits(0.1f)));  

结果是:11111110111001100110011001100110100000000000000000000000000000

很明显不一样

二进制小数的表达形式

根据国际标准IEEE 754,任意一个二进制浮点数V可以表示成下面的形式:

 

 

  (1)(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。

  (2)M表示有效数字,大于等于1,小于2。

  (3)2^E表示指数位。

举个例子 用二进制表达十进制的 0.2 

0.01 = 1/4 = 0.25 ,太大

0.001 =1/8 = 0.125 , 又太小

0.0011 = 1/8 + 1/16 = 0.1875 , 逼近0.2了

0.00111 = 1/8 + 1/16 + 1/32 = 0.21875 , 又大了

0.001101 = 1/8+ 1/16 + 1/64 = 0.203125 还是大

0.0011001 = 1/8 + 1/16 + 1/128 = 0.1953125 这结果不错

0.00110011 = 1/8+1/16+1/128+1/256 = 0.19921875

.......................................................

第一种方法:转换成字符串

如果要比较的两个浮点数数据的字符串精度相等,可以将数据转换成string然后借助string的equals方法来间接实现比较两个double数据是否相等。注意这种方法只适用于比较精度相同的数据,并且是只用用于比较是否相等的情况下,不能用来判断大小。

Float.toString(453.2348f).equals(Float.toString(0.342f))

Double.toString(0.8456d).equals(Float.toString(0.242f))

第二种方法:使用sun提供的Double.doubleToLongBits()方法

该方法可以将double转换成long型数据,从而可以使double按照long的方法(<, >, ==)判断是否大小和是否相等。

Double.doubleToLongBits(0.01) == Double.doubleToLongBits(0.01) 
Double.doubleToLongBits(0.02) > Double.doubleToLongBits(0.01) 
Double.doubleToLongBits(0.02) < Double.doubleToLongBits(0.01)

第三种方法:误差内比较

对于double类型,比如double d1=0.0000001,double d2=0d 当判断两个数据d1和d2是否相等的时候,一般不直接使用

if(d1==d2)

    ...

第四种办法:BigDecimal类型

double a = 0.001; 
double b = 0.0011; 
BigDecimal data1 = new BigDecimal(a); 
BigDecimal data2 = new BigDecimal(b); 
data1.compareTo(data2) 
非整型数,运算由于精度问题,可能会有误差,建议使用BigDecimal类型!

反例1:用equals方法可以吗

Double a = Double.valueOf("0.0");  
Double b = Double.valueOf("-0.0");  
System.out.println(a.equals(b));  

false

Double a = Math.sqrt(-1.0);  
Double b = 0.0d / 0.0d;  
Double c = a + 200.0d;  
Double d = b + 1.0d;  
System.out.println(a.equals(b));  
System.out.println(b.equals(c));  
System.out.println(c.equals(d));  

true
true
true

equals方法是比较2个对象是否等值,而不是对象的值是否相等

反例2:用compareTo方法可以吗

public static void main(String[] args) {

        Double a = Double.valueOf("0.0");
        Double b = Double.valueOf("-0.0");
        System.out.println(a.compareTo(b));

        //1

        Double a1 = Math.sqrt(-1.0);
        Double b1 = 0.0d / 0.0d;
        Double c1 = a1 + 200.0d;
        Double d1 = b1 + 1.0d;
        System.out.println(a1.compareTo(b1));
        System.out.println(b1.compareTo(c1));
        System.out.println(c1.compareTo(d1));

        //0
        //0
        //0
    }

 a和b表示为NaN(Not a Number) ,并不是数字,无法比较。

总结

在进行浮点数比较的时候,主要需要考虑3个因素

  • NaN
  • 无穷大/无穷小
  • 舍入误差

所以,要比较浮点数是否相等,需要做的事情是:

  • 排除NaN和无穷
  • 在精度范围内进行比较

参考连接

https://blog.csdn.net/renwotao2009/article/details/51637163

http://en.wikipedia.org/wiki/Floating_point

https://blog.csdn.net/wcxiaoych/article/details/42806313#

https://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html

本公众号分享自己从程序员小白到经历春招秋招斩获10几个offer的面试笔试经验,其中包括【Java】、【操作系统】、【计算机网络】、【设计模式】、【数据结构与算法】、【大厂面经】、【数据库】期待你加入!!!

1.计算机网络----三次握手四次挥手
2.梦想成真-----项目自我介绍

3.你们要的设计模式来了

4.一字一句教你面试“个人简介”

5.接近30场面试分享

6.你们要的免费书来了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

double类型(浮点数)是否相等的判断方法 的相关文章

  • JVM工具-jstack

    jstack 打印线程堆栈信息 支持支持本地java进程 core文件以及远程java进程 命令格式 jstack options pid jstack options executable core jstack options serv
  • mac上使用IntelliJ IDEA运行项目

    一 Mac OSX系统下安装Tomcat 1 下载Tomcat官方下载地址 2 解压Tomcat到目录 Library 中 并把文件夹名由 apache tomcat 6 0 16 改为 Tomcat 3 打开 应用程序 Applicati
  • 3、Java的If语句与For循环

    一 语句 条件语句 根据不同的条件 执行不同的语句 if if else if else if if else if else if else switch 循环语句 重复执行某些动作 for while do while 1 1 if语句
  • Java特训的第一天——开篇

    我是一名刚入门的Java菜鸟 我选择Java的原因是因为其语法简单 功能强大 从web 到桌面 到嵌入式 无所不能 下面我将谈一谈我对Java语言的认识 Java语言概述 关于Java的介绍网上有很详细的阐述 我在这里就不再细述了 下面只简
  • Java基础——strictfp关键字

    关键字strictfp是strict float point的缩写 指的是精确浮点 它是用来确保浮点数运算的准确性 JVM在执行浮点数运算时 如果没有指定strictfp关键字 此时计算结果可能会不精确 而且计算结果在不同平台或厂商的虚拟机
  • java中的file.encoding属性到底由什么决定?

    首先先上一段代码 public class PropertiesTest public static void main String args System out println file encoding System getProp
  • MQ的基本原理是怎样的?MQ的优点有哪些?MQ的核心概念包括哪些?MQ的消息传递模式有哪些?

    1 MQ的基本原理是怎样的 MQ 消息队列 是一种面向消息的中间件 用于实现不同系统之间的异步通信 其基本原理如下 生产者 Producer 将消息发送到消息队列中 而不是直接发送给消费者 Consumer 消息队列将接收到的消息存储在内部
  • java Map集合

    目录 一 介绍 二 HashMap 三 TreeMap 四 LinkedHashMap 一 介绍 Java中的Map是一种键值对的集合数据类型 用于存储无序的 不重复的键值对 它提供了快速的查找和访问功能 可以根据键来获取值 常见的Map实
  • javaSE进阶1之static用法

    JavaSE进阶 静态关键字 static static关键字的作用 成员变量分类 静态成员变量 实例成员变量 static修饰成员变量内存原理 static 修饰成员方法的基本用法 成员方法的分类 static修饰成员方法内存原理 sta
  • 【Java】Java中的String类

    文章目录 一 认识 String 类 二 String 类的常用方法 2 1 构造方法 2 2 String 类对象之间的比较 2 3 字符串查找 2 4 字符串的转换 2 5 字符串替换 2 6 字符串拆分 2 7 字符串截取 2 8 字
  • Java中的IO流如何理解——精简

    目录 引言 缓冲流 字节缓冲流 字符缓冲流 转换流 字符输入转换流 字符输出转换流 序列化和反序列化 对象序列化 对象反序列化 打印流 Properties 引言 通过前面的简单学习 我们已经能够大致了解了关于文件的操作 但是能够明显感受到
  • 《编写高质量代码:改善Java程序的151个建议》读书笔记

    编写高质量代码 改善Java程序的151个建议 秦小波 67个笔记 前言 本书附带有大量的源码 下载地址见华章网站www hzbook com 建议11 养成良好习惯 显式声明UID SerialVersionUID 也叫做流标识符 Str
  • MVC模型图

    MVC图
  • jeecgboot问题解决方案

    常见问题Q A JEECG老版在线文档 点击进入 1 后台访问提示token错误 报错截图 解决方案 JeecgBoot后台的所有请求访问 增加了token机制 所以不能直接访问后台 而需要通过前台登录才能访问 默认前台访问地址 http
  • 求一个数组的最大值最小值及其下标

    求一个数组的最大值最小值及其下标 思路 假定一个数为最大值 如果有个数比假定的最大值还大 那么该数就为最大值 最小值同理 使用for循环 public class MaxMin public static void main String
  • IDEA 编写JDBC 第一个示例

    知心惟有雕梁燕 自来相伴 东风不管琵琶怨 落花吹遍 一 新建一个Module 二 在此Module下新建一个包 在包再建一个包 命名为lib 三 导入mysql驱动 四 将mysql驱动添加到项目的库里 五 代码实现 package Con
  • java基础之HashSet详解

    HashSet详解 HashSet是基于HashMap实现的一个单列存储的集合类 将所有的数据存在HashMap的key值中 而value全部使用一个Object对象存储 继承关系 public class HashSet
  • java连接oracle出现ORA-12505错误

    问题 sqlplus可以连接 但java连接报错 ORA 12505 ORA 12505 TNS listener does not currently know of SID given in connect descr 解析 原因 数据
  • 黑豹程序员-统一身份认证接口

    术语和定义 1 IAM Identity Access Manager 统一身份认证系统 2 IDM Identity Manager 身份管理 3 SSO Single Sign On 单点登录 4 AD Active Directory
  • 黑豹程序员-字符串中查找出重复的字符串

    Collections frequency codeList element 字符串element 在codeList集合中重复的次数 List

随机推荐

  • blender05乐高中级版

    1 新建一个2 4的平面 2 点击环切 将平面切割为两个平面 3 选中两个面 按下I内部挤压 变成下面的样子 但其实这样不对 x和y的距离不一样长 所以要回到物体模式 点击应用 点击缩放 将x y z的缩放比例都设置为1 4 继续环切 成下
  • IAR使用之破解

    http www amobbs com thread 5526625 1 1 html 对于学习AVR单片机的人来说 IAR是必不可少的开发软件 IAR以编译效率高著称 相比AVR STUDIO 6 0 它有小巧的体型 这点对于电脑配置不是
  • 大数据是什么意思

    在大数据的越来越火的今天 相信很多朋友都不清楚大数据到底是什么 可以解决实际生活中的什么问题 那么今天科多大数据老师就给各位小伙伴儿普及下大数据的概念吧 大数据到底是什么勒 大数据 是一个体量特别大 数据类别特别大的数据集 并且这样的数据集
  • 请用 python 打印出 10000 以内的对称数 (对称数特点:数字左右对称,如:1,2,11,121,1221 等)

    就用正序等于倒序的办法就可解决 lis for i in range 1 10000 i str i if i i 1 lis append i print lis ps 这个面试题在这么大的网站中找起来居然这么费劲 不是收费就是广告
  • 【硬创邦】跟hoowa学做智能路由(二):从芯片开始

    上一章我们讲了 这次DIY活动的来龙去脉 本章我们将一起了解下路由器的架构 芯片 操作系统相关的知识 我们的目标是让大家都能做智能路由 所以hoowa会尽可能少涉及到嵌入式的知识 因为这孩子本身学习就不好 他自己也害怕那些所谓的各种 定义
  • delphi xe10.2 FIREDAC 三种连接

    以下都是在DELPHI XE10 2中测试通过 FireDAC supports three distinct options for connecting to your database These are Temporary conn
  • 越狱iOS设备利用itms-services协议,实现Safari一键安装IPA

    http kryhear asia blog 2012 07 14 use itms services install ipa to a jailbreak ios device 利用MobileInstallation实现IPA程序安装后
  • Python 3.8 pandas 安装不了

    如果您在安装 Pandas 时遇到了问题 有以下几种常见解决方案 检查您的 Python 版本是否为 3 8 Pandas 对于 Python 3 8 的支持可能不是很好 因此您可以尝试安装旧版本的 Pandas 检查您是否安装了所有 Pa
  • C语言这么厉害,它自身又是用什么语言写的?

    作者 码农翻身刘欣 出自 码农翻身 ID coderising 这是来自我的星球的一个提问 C语言本身用什么语言写的 换个角度来问 其实是 C语言在运行之前 得编译才行 那C语言的编译器从哪里来 用什么语言来写的 如果是用C语言本身来写的
  • opencv中图像的旋转

    opencv中进行图像旋转的方法 flip函数 rotate函数但是这两种函数只能进行90 180 270的旋转 CV EXPORTS W void flip InputArray src OutputArray dst int flipC
  • 《数据挖掘导论》笔记(四)

    分类 本章介绍分类的基本概念 讨论诸如模型的过拟合等关键问题 并提供评估和比较分类技术性能的方法 尽管本章主要关注一种称作决策树归纳的技术 但是本章讨论的大部分内容也适用于其他的分类技术 预备知识 分类任务的输入数据是记录的集合 每条记录称
  • SQL查询半年内没有违纪记录,并且期末考试总分为每个班级前10名的学生名单。(日期函数、where、group by)

    面试题 有三张表 学生表 期末成绩表 违纪表 查询半年内没有违纪记录 并且期末考试总分为每个班级前10名的学生名单 解题思路 可以把这个复杂业务问题 使用多维度拆解分析方法 拆解为以下3个子问题 1 从 违纪表 中查询半年内有违纪记录的学生
  • MMClassification Python 教程(二)

    若纠结查看格式可以移步 学习笔记https study chenkequan cn E6 B7 B1 E5 BA A6 E5 AD A6 E4 B9 A0 E6 A1 86 E6 9E B6 openLab E7 B3 BB E5 88 9
  • FBX与Opengl骨骼系统

    转自 http blog csdn net mink365 article details 6328033 FBX是Autodesk提供的一个三维模型格式 由于AutoDesk已经收购了Maya 3D max等流行三维建模软件 FBX可以说
  • hadoop集群配置

    一个具体的配置 这里只搭建一个三台主机的小机群 10 37 128 2 master namenode jobtracker master 主机名 10 37 128 3 salve datanode tasktracker slave1
  • 在服务器上部署 Nginx 并设置图片服务器

    当您在服务器上部署 Nginx 并设置图片服务器时 以下是大致的步骤 安装 Nginx 使用适用于您的操作系统的包管理器安装 Nginx 编辑 Nginx 配置文件 找到 Nginx 的配置文件 通常位于 etc nginx nginx c
  • matplotlib柱状图给指定的柱换颜色_Python全栈之路-15-matplotlib

    本文jupyter notebook 地址 github com import numpy as np import pandas as pd import matplotlib import matplotlib pyplot as pl
  • Redis持久化RDB与AOF

    前言 我们知道Redis是一款内存服务器 就算我们对自己的服务器足够的信任 不会出现任何软件或者硬件的故障 但也会有可能出现突然断电等情况 造成Redis服务器中的数据失效 因此 我们需要向传统的关系型数据库一样对数据进行备份 将Redis
  • MySQL完整笔记

    注 本篇大部分内容都是尚硅谷mysql课程的笔记 如果需要课程以及源码 请至官网下载 下载地址 数据库 介绍 1 概念 1 DB 数据库 保存一组有组织的数据的容器 2 DBMS 数据库管理系统 又称为数据库软件 产品 用于管理DB中的数据
  • double类型(浮点数)是否相等的判断方法

    浮点数不精确 计算机内部无法用二进制的小数来精确的表达 public class Tesz public static void main String args double a 0 1 float c 0 1f System out p