JAVA - 判断两个浮点数相等
JAVA - 判断两个浮点数相等
背景知识
float型和double型是JAVA的基本类型,用于浮点数表示,在JAVA中float型占4个字节32位,double型占8个字节64位,一般比较适合用于工程测量计算中,其在内存里的存储结构如下:
float型:
符号位(1 bit)
指数(8 bit)
尾数(23 bit)
double型:
符号位(1 bit)
指数(11 bit)
尾数(52 bit)
注意:从左到右是从低位到高位,而在计算机内部是采用逆序存储的。
JAVA中float型和double型是不能被计算机精确存储的。以double类型数据1.10举例计算机如何将浮点型数据转换成二进制存储:
整数部分:1,转换成二进制1
小数部分:0.1
0.1*2=0.2取整数部分0,基数=0.2
0.2*2=0.4取整数部分0,基数=0.4
0.4*2=0.8取整数部分0,基数=0.8
0.8*2=1.6取整数部分1,基数=1.6-1=0.6
0.6*2=1.2取整数部分1,基数=1.2-1=0.2
0.2*2=0.4取整数部分0,基数=0.4
···
直至基数为0。
1.1用二进制表示为:1.000110……,即0.1 = 0*2^(-1)+0*2^(-2)+0*2^(-3)+1*2^(-4)+……而double型的小数部分只有52位,当向后计算 52位后基数还不为0时,后面的部分只能舍弃,从这里可以看出float型、double型并不能准确表示每一位小数。
因此。程序中应尽量避免浮点数的比较。在循环中,检测两个浮点数是否相等需要格外小心,如下的for循环可能永远不会结束:
for(double i = 0; i != 10; i += 0.1);
浮点数能表示的精度是有限的,在计算过程中不可避免的会出现截尾而损失精度,所以如果要判断一个浮点数double_x是否等于0,用double_x == 0这样的判断是不合适的,如果double_x是一系列计算的结果或者是外部传感器的输入值,那么它几乎不可能是0,它大概率是一个接近0的小数,比如0.000002,
比较double数据是否相等的方法
方法一:若精度要求不高,比如因为传感器有误差,小于0.001的数都可以认为等于0,那么就定义epsilon = 0.001:
- final double epsilon = 0.001;
- double double_x = 0.0;
- if(Math.abs(double_x - 0) < epsilon)
- {
- System.out.println("true");
- }
方法二:转换成字符串之后用equals方法比较
如果要比较的两个double数据的字符串精度相等,可以将数据转换成String然后借助String的equals方法来间接实现比较两个double数据是否相等。
Double.toString(double_x).equals(Double.toString(double_y))
注意:这种方法只适用于比较精度相同的数据,并且是只用用于比较是否相等的情况下,不能用来判断大小。
方法三:转换成Long之后用==方法比较
使用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)
方法四:使用BigDecimal类型的equals方法或compareTo方法
类加载:
import java.math.BigDecimal;
使用字符串形式的float型和double型构造BigDecimal:BigDecimal(String val)。BigDecimal的euquals方法是先判断要比较的数据类型,如果对象类型一致前提下同时判断精确度(scale)和值是否一致;compareTo方法则不会比较精确度,把精确度低的那个对象转换为高精确度,只比较数值的大小。
- System.out.println(new BigDecimal("1.2").equals(new BigDecimal("1.20"))); //输出false
- System.out.println(new BigDecimal("1.2").compareTo(new BigDecimal("1.20")) == 0); //输出true
- System.out.println(new BigDecimal(1.2).equals(new BigDecimal("1.20"))); //输出false
- System.out.println(new BigDecimal(1.2).compareTo(new BigDecimal("1.20")) == 0); //输出false
- System.out.println(new BigDecimal(1.2).equals(new BigDecimal(1.20))); //输出true
- System.out.println(new BigDecimal(1.2).compareTo(new BigDecimal(1.20)) == 0);//输出true
原地址:https://blog.csdn.net/bupa900318/article/details/80553695
JAVA - 判断两个浮点数相等的更多相关文章
- Java 判断两个对象是否相等
一.使用 == 与 equals == : 它的作用是判断两个对象的地址是不是相等.即,判断两个对象是不是同一个对象.(基本数据类型==比较的是值,引用数据类型==比较的是内存地址) equals() ...
- Java判断两个List是否相同
1.利用Java中为List提供的方法retainAll() /** * 判断两个List内的元素是否相同 * <p> * 此方法有bug 见Food.class * * @param l ...
- Java比较两个浮点数
浮点数的基本数据类型不能用==比较,包装数据类型不能用 equals 比较 浮点数的表示 在计算机系统中,浮点数采用 符号+阶码+尾数 进行表示.在Java中,单精度浮点数float类型占32位,它的 ...
- java 判断两个时间相差的天数
1.实现目标 输入:两个日期 输出:两个日期相差的天数 2.代码实现 方法1: 通过Calendar类的日期比较.注意:这里需要考虑一下: 日期是跨年份的,如一个是2012年,一个是2015年的 ...
- Java判断两个时间相差的天数
1.实现目标 输入:两个日期 输出:两个日期相差的天数 2.代码实现 方法1: 通过Calendar类的日期比较.注意:这里需要考虑一下: 日期是跨年份的,如一个是2012年,一个是2015年的 ...
- java判断两个时间相差得天数
方法一:通过Calendar类得日期比较,在这需要考虑闰年和平年,也要考虑跨年份 /** * date2比date1多的天数 * @param date1 * @param date2 * @retu ...
- java 判断两个数是否异号
java 整型int占4个字节32位,两个数异或后移动31位判断结果,如果是1则异号,如果是0则同号 public class ShowEnviromentViarible { public stat ...
- java 判断两个时间段是不是有交集
如上图:X Y Z 分别为传来的开始时间可能位于数据库中时间段的位置. X有三种可能 即传来的开始时间为与数据可中某条数据的开始位置! 这样他的结束时间就有三种可能 1.位于 ...
- java 判断两个时间段是否有交集
/* 开始时间 */ Date leftStartDate = feesPreferential.getPreferentialStartTime(); /* 结束时间 */ Date leftEnd ...
- java 判断两个list是否相等
/** * 队列比较 * @param <T> * @param a * @param b * @return */ public static <T extends Compara ...
随机推荐
- easyui subGrid实现
$(function(){ $('#dg').datagrid({ view: detailview, detailFormatter:function(index,row){ return '< ...
- R语言码农的Scala学习心得
为了MLib,最近是铁了心要学好Spark.关注本博客的朋友应该知道我的主力语言是R,无论是训练模型还是做Elasticsearch,都是通过R脚本来操作的.之前的<通过 Spark R 操作 ...
- 阿里云部署OSS对接TP项目
1.配置文件写入参数 domain为阿里云oss存储实例要绑定的域名 2.获取accesskeyId和secret 注册用户 出现下图,选择"开始使用子用户Access Key" ...
- R7-1 求10个点到原点的距离和
R7-1 求10个点到原点的距离和 分数 15 全屏浏览题目 切换布局 作者 张高燕 单位 浙大城市学院 求10个点到原点的距离和.输入10个点的坐标,计算并输出这些点到原点的距离和.定义函数dist ...
- CF1534F2 Falling Sand (Hard Version)
个人思路: 每个点向相邻沙子连边,向本列和相邻 \(2\) 列下方第一个沙子连边. 对于一个 DAG,所有入度为 \(0\) 的点会覆盖全部点.我们缩点即可通过 F1. 但是这样做是过不了 F2 的. ...
- 动态路由里,将component字符串改变为路由懒加载方法
一.import写法 报错 function loadPageByRoutes(str) { // 传入的str为 '@/views/Home.vue' 这种格式 return () => im ...
- 端口被占用 for mac
启用项目提示端口被占用 解决方案: lsof -i : 3010 杀死占用的进程 kill -9 4804 重新启动
- continue的使用
continue是终止本次循环,进行下一个循环如果要跳到最开始的循环abc : for(){ for(){ for(){ continue abc; } }}
- Jmeter添加while控制器
通过添加while控制器,可以实现条件+循环判断,使while控制器内的子线程根据之前线程的返回(while控制器内外变量皆可)进行触发+循环的控制. 原理如下:通过Condition判断条件语句是否 ...
- Django基础篇 03- Models的属性与字段
1.models字段类型 AutoField():一个IntegerField,根据可用ID自动递增.如果没指定主键,就创建它自动设置为主键. IntegerField():一个整数: FloatFi ...