equals不等于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:
1.
final double epsilon = 0.001;
2.
double double_x = 0.0;
3.
if(Math.abs(double_x - 0) < epsilon)
4.
{
5.
System.out.println("true");
6.
}
⽅法⼆:转换成字符串之后⽤equals⽅法⽐较
如果要⽐较的两个double数据的字符串精度相等,可以将数据转换成String然后借助String的equals⽅法来间接实现⽐较两个double数据是否相等。
注意:这种⽅法只适⽤于⽐较精度相同的数据,并且是只⽤⽤于⽐较是否相等的情况下,不能⽤来判断⼤⼩。
⽅法三:转换成Long之后⽤==⽅法⽐较
使⽤Sun提供的Double.doubleToLongBits()⽅法,该⽅法可以将double转换成long型数据,从⽽可以使double按照long的⽅法(<, >, ==)判断是否⼤⼩和是否相等。
1.
Double.doubleToLongBits(0.01) == Double.doubleToLongBits(0.01)
2.
Double.doubleToLongBits(0.02) > Double.doubleToLongBits(0.01)
3.
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⽅法则不会⽐较精确度,把精确度低的那个对象转换为⾼精确度,只⽐较数值的⼤⼩。
1.
System.out.println(new BigDecimal("1.2").equals(new BigDecimal("1.20"))); //输出false
2.
System.out.println(new BigDecimal("1.2")pareTo(new BigDecimal("1.20")) == 0); //输出true
3.
4.
System.out.println(new BigDecimal(1.2).equals(new BigDecimal("1.20"))); //输出false
5.
System.out.println(new BigDecimal(1.2)pareTo(new BigDecimal("1.20")) == 0); //输出false
6.
7.
System.out.println(new BigDecimal(1.2).equals(new BigDecimal(1.20))); //输出true
8.  System.out.println(new BigDecimal(1.2)pareTo(new BigDecimal(1.20)) == 0);//输出true
原地址:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。