博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 中 BigDecimal 的 equals() 与 compareTo() 的区别
阅读量:5739 次
发布时间:2019-06-18

本文共 4039 字,大约阅读时间需要 13 分钟。

hot3.png

        这两天在设计金额表字段类型的时候,在 double 和 decimal 之间犹豫了半天,讲道理应该是用decimal的,但是以前的人的表设计是用double的,最终我还是坚持真理用了decimal,虽然都是浮点数,但是用 int(单位:分)再转换为 double 来显示都比直接用 double 靠谱,double 可能会发生一些精度不准的现象,而 decimal 是对象,用方法操作,不直接用运算符运算,在金额方面是很安全的。

【jre7】:equals():

        可以看到BigDecimal的euquals方法是先判断要比较的数据类型,如果对象类型一致前提下同时判断精确度(scale)和值(BigInteger的equals方法)是否一致。

/** * Compares this {@code BigDecimal} with the specified * {@code Object} for equality.  Unlike {@link * #compareTo(BigDecimal) compareTo}, this method considers two * {@code BigDecimal} objects equal only if they are equal in * value and scale (thus 2.0 is not equal to 2.00 when compared by * this method). * * @param  x {@code Object} to which this {@code BigDecimal} is *         to be compared. * @return {@code true} if and only if the specified {@code Object} is a *         {@code BigDecimal} whose value and scale are equal to this *         {@code BigDecimal}'s. * @see    #compareTo(java.math.BigDecimal) * @see    #hashCode */@Overridepublic boolean equals(Object x) {    if (!(x instanceof BigDecimal))        return false;    BigDecimal xDec = (BigDecimal) x;    if (x == this)        return true;    if (scale != xDec.scale)        return false;    long s = this.intCompact;    long xs = xDec.intCompact;    if (s != INFLATED) {        if (xs == INFLATED)            xs = compactValFor(xDec.intVal);        return xs == s;    } else if (xs != INFLATED)        return xs == compactValFor(this.intVal);    return this.inflate().equals(xDec.inflate());}

 

【jre7】:compareTo()

        可以看到这个方法里面有个matchScale的处理,意思是把精确度低的那个对象转换为高精确度,然后再进行比较(同样是BigInteger的compareTo方法)。

/** * Compares this {@code BigDecimal} with the specified * {@code BigDecimal}.  Two {@code BigDecimal} objects that are * equal in value but have a different scale (like 2.0 and 2.00) * are considered equal by this method.  This method is provided * in preference to individual methods for each of the six boolean * comparison operators ({@literal <}, ==, * {@literal >}, {@literal >=}, !=, {@literal <=}).  The * suggested idiom for performing these comparisons is: * {@code (x.compareTo(y)} <op> {@code 0)}, where * <op> is one of the six comparison operators. * * @param  val {@code BigDecimal} to which this {@code BigDecimal} is *         to be compared. * @return -1, 0, or 1 as this {@code BigDecimal} is numerically *          less than, equal to, or greater than {@code val}. */public int compareTo(BigDecimal val) {    // Quick path for equal scale and non-inflated case.    if (scale == val.scale) {        long xs = intCompact;        long ys = val.intCompact;        if (xs != INFLATED && ys != INFLATED)            return xs != ys ? ((xs > ys) ? 1 : -1) : 0;    }    int xsign = this.signum();    int ysign = val.signum();    if (xsign != ysign)        return (xsign > ysign) ? 1 : -1;    if (xsign == 0)        return 0;    int cmp = compareMagnitude(val);    return (xsign > 0) ? cmp : -cmp;}

        matchScale():

/** * Match the scales of two {@code BigDecimal}s to align their * least significant digits. * * 

If the scales of val[0] and val[1] differ, rescale * (non-destructively) the lower-scaled {@code BigDecimal} so * they match. That is, the lower-scaled reference will be * replaced by a reference to a new object with the same scale as * the other {@code BigDecimal}. * * @param val array of two elements referring to the two * {@code BigDecimal}s to be aligned. */private static void matchScale(BigDecimal[] val) { if (val[0].scale == val[1].scale) { return; } else if (val[0].scale < val[1].scale) { val[0] = val[0].setScale(val[1].scale, ROUND_UNNECESSARY); } else if (val[1].scale < val[0].scale) { val[1] = val[1].setScale(val[0].scale, ROUND_UNNECESSARY); }}

 

做个简单测试:

System.out.println(new BigDecimal("1.2").equals(new BigDecimal("1.20")));  //输出falseSystem.out.println(new BigDecimal("1.2").compareTo(new BigDecimal("1.20")) == 0); //输出true

 

结论:

        对于BigDecimal的大小比较,用equals方法的话会不仅会比较值的大小,还会比较两个对象的精确度,而compareTo方法则不会比较精确度,只比较数值的大小

转载于:https://my.oschina.net/NamiZone/blog/1611174

你可能感兴趣的文章
用spring-data-redis实现类似twitter的网站(转)
查看>>
Unity3D 之武器系统冷却功能的实现方式
查看>>
安卓中运行报错Error:Execution failed for task ':app:transformClassesWithDexForDebug'解决
查看>>
Oracle 表空间与数据文件
查看>>
关于拉格朗日乘子法和KKT条件
查看>>
Godray
查看>>
音视频编解码开发经验2
查看>>
05-移动端开发教程-CSS3兼容处理
查看>>
vue - static(.gitkeep)
查看>>
逻辑编程入门--clojure.core.logic
查看>>
Mysql的性能优化
查看>>
类型实例的创建位置、托管对象在托管堆上的结构
查看>>
如何解决XP局域网访问故障方法
查看>>
WebCast《实战ASP.NET AJAX系列课程(2):使用客户端框架创建“纯粹”的Ajax应用程序》相关资源...
查看>>
数据库安全防范黑客入侵
查看>>
编写Pascal代码
查看>>
wxWidgets 的自定义分隔条控件
查看>>
Alamps学习设计模式之Proxy模式(一骑红尘妃子笑版)
查看>>
如何使页面中的INPUT按指定的顺序移动焦点{转}
查看>>
JOJ 2453 Candy
查看>>