Float和Double是浮点型数值,实际存储在内存的数值并非是精确的小数,这是因为计算机是以二进制存储数据的( 具体解释)
简单计算时,我们可以忽略数据精度的问题,直接使用java的基本数据类型Float和Double,精确计算时我们必须使用BigDecimal类型。
但是在对两个数据做比较时,如果使用<,>,==,等进行比较,则Float,Double和BigDecimal都无法得到正确的结果(也就是我们期望的结果)。下面我们以相等比较为例,复现这个问题
问题复现
import java.math.BigDecimal;
public class test {
public int i1 = 1;
public int i2 = 1;
public Float f1 = 1.1f;
public Float f2 = 1.1f;
public Double d1 = 1.1;
public Double d2 = 1.1;
public BigDecimal b1 = new BigDecimal(1.1);
public BigDecimal b2 = new BigDecimal(1.1);
public static <T> void directCompare(T t1,T t2){
System.out.println(t1.getClass()+"类型:"+t1.toString()+"和"+t2.toString()+"是否相等:"+(t1==t2));
}
public static void main(String[] args) {
test te = new test();
te.directCompare(te.i1,te.i2);
te.directCompare(te.f1,te.f2);
te.directCompare(te.d1,te.d2);
te.directCompare(te.b1,te.b2);
}
}
运行结果
class java.lang.Integer类型:1和1是否相等:true
class java.lang.Float类型:1.1和1.1是否相等:false
class java.lang.Double类型:1.1和1.1是否相等:false
class java.math.BigDecimal类型:1.100000000000000088817841970012523233890533447265625和1.100000000000000088817841970012523233890533447265625是否相等:false
int是符合预期的
Float和Double虽然输入和输出都是相等的1.1,但是使用比较时并不相等
BigDecimal不是java的基本数据类型,但BigDecimal的变量也无法精确地存储在内存中
解决方法
建议使用compareTo方法
import java.math.BigDecimal;
public class test {
public int i1 = 1;
public int i2 = 1;
public Float f1 = 1.1f;
public Float f2 = 1.1f;
public Double d1 = 1.1;
public Double d2 = 1.2;
public BigDecimal b1 = new BigDecimal(1.1);
public BigDecimal b2 = new BigDecimal(1.0);
public static <T> void directCompare(T t1,T t2){
System.out.println(t1.getClass()+"类型:"+t1.toString()+"和"+t2.toString()+"是否相等:"+(t1==t2));
}
public static <T extends Comparable> void newCompare(T t1,T t2){
System.out.println(t1.getClass()+"类型:"+t1.toString()+"和"+t2.toString()+"是否相等:"+(t1.compareTo(t2)));
}
public static void main(String[] args) {
test te = new test();
te.newCompare(te.i1,te.i2);
te.newCompare(te.f1,te.f2);
te.newCompare(te.d1,te.d2);
te.newCompare(te.b1,te.b2);
}
}
运行结果
class java.lang.Integer类型:1和1是否相等:0
class java.lang.Float类型:1.1和1.1是否相等:0
class java.lang.Double类型:1.1和1.2是否相等:-1
class java.math.BigDecimal类型:1.100000000000000088817841970012523233890533447265625和1是否相等:1
0表示相等
-1表示小于<
1表示大于>
问题解决