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 ...
随机推荐
- 【git】2.5远程仓库的使用
资料来源 (1) https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%BF%9C%E7%A8%8B%E4%BB%93%E5%BA%93% ...
- python的排序问题
python的排序方法有两个 1 nums.sort() # 原数组上排序, 没有返回值, nums变为有序 2 # 或者 3 nums = sorted(nums) # 原数组不变, 会返回一个排好 ...
- ISTQB软件测试初级认证模拟题
参考地址 http://www.docin.com/p-297467364.html 第一章:软件测试基础(18%) 1.学习目标 1.1 为什么需要软件测试? (K2) ① 通过具体的例子,来描述软 ...
- golang 不再使用原生的log, 使用固定的zap logger
最主要一点, zap的可以给出详细的log信息, 形如 2023-02-10T09:24:55.707+0800 INFO v3web/main.go:196 [2023-02-10 09:24:55 ...
- spring boot整合druid
其实网上有很多例子可供参考,主要是在整合的过程中遇到了一些问题,方便记录下.另外例子可参考以下两个链接: https://www.jianshu.com/p/e3cd2e1c2b0c https:// ...
- 【C++复习】第八章 多态性(1)(多态类型、运算符重载)
1.多态性 1.1 什么是多态? 多态是指相同消息被不同对象接收后导致不同的行为,所谓消息是指对类成员函数的调用,不同的行为是指不同的实现,也就是调用了不同的函数. 消息在C++编程中指的是对类的成员 ...
- ComPiler200004:Library-Oriented Programming
https://www.aliyun.com/jiaocheng/403982.html 摘要: Creating a simple, encapsulated, maintainable libra ...
- 洛谷 P4454 [CQOI2018]破解D-H协议
题目 https://www.luogu.com.cn/problem/P4454 杂题乱做ing... 思路 首先我们把式子列一下: \(g^a\equiv A(mod P)\) \(g^b\equ ...
- 【C学习笔记】day2-1 给定两个整形变量的值,将两个值的内容进行交换
#include<stdio.h> int main() { int a=0, b=1,temp; temp = b; b = a; a = temp; //printf("%d ...
- Java数组之什么是数组?+ 数组的声明和创建
数组 数组是相同类型数据的有序集合. 数组描述的是相同类型的若干个数据,按照一定的先后次序排序组合而成. 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们. 数组声明创建 首先 ...