首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在groovy/grails中在BigDecimal上使用比较操作符安全吗?

在groovy/grails中在BigDecimal上使用比较操作符安全吗?
EN

Stack Overflow用户
提问于 2015-05-07 12:16:12
回答 3查看 4.3K关注 0票数 5

比较两个BigDecimals的方法是使用compareTo()方法,并检查结果是-1、0还是1。

代码语言:javascript
复制
BigDecimal a = new BigDecimal("1.23")
BigDecimal b = new BigDecimal("3.45")
if (a.compareTo(b) > 0)) { }

我看到有些人在grails中使用这种格式:

代码语言:javascript
复制
 if (a > b) {  }

这样做正确吗?也就是说,它会得到正确的小数,还是它是转换成浮点或类似的,并进行比较?

使用"==“与使用equals()如何?

这样做的后果是什么?

代码语言:javascript
复制
BigDecimal a = new BigDecimal("1.00")
BigDecimal b = new BigDecimal("1")
assert (a==b)

这似乎是可行的,但我们已经让它在Java中根深蒂固,不去做这种事情。

+=怎么样?例如:

代码语言:javascript
复制
a+=b?

这是不是和

代码语言:javascript
复制
a = a.add(b)

你在哪里发现这种东西的?我有两本groovy书籍,不幸的是,我没有提到BigDecimal比较或算术,只提到了转换/声明。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-07 13:37:28

Groovy允许重载操作符。当类型实现某些方法时,可以在该类型上使用相应的运算符。

对于+,要实现的方法是加号,而不是添加。

对于大于或小于比较,Groovy在对象上查找一个compareTo方法,对于==,它查找一个名为equals的方法。(如果您想像在Java中使用==一样比较引用,则必须使用is。)

下面是一个常用数学运算符的表,以及用于重载它们的方法:

代码语言:javascript
复制
Operator     Method
a + b        a.plus(b)
a - b        a.minus(b)
a * b        a.multiply(b)
a / b        a.divide(b)
a++ or ++a   a.next()
a-- or --a   a.previous()
a << b       a.leftShift(b)

您可以看到,BigDecimal重载了这些方法中的一些(对于加号、减号、乘法和除法,操作符重载,但是对于next、previous或leftShift没有重载):

代码语言:javascript
复制
groovy:000> BigDecimal.methods*.name
===> [equals, hashCode, toString, intValue, longValue, floatValue, doubleValue,
byteValue, shortValue, add, add, subtract, subtract, multiply, multiply, divide,
 divide, divide, divide, divide, divide, remainder, remainder, divideAndRemainde
r, divideAndRemainder, divideToIntegralValue, divideToIntegralValue, abs, abs, m
ax, min, negate, negate, plus, plus, byteValueExact, shortValueExact, intValueEx
act, longValueExact, toBigIntegerExact, toBigInteger, compareTo, precision, scal
e, signum, ulp, unscaledValue, pow, pow, movePointLeft, movePointRight, scaleByP
owerOfTen, setScale, setScale, setScale, stripTrailingZeros, toEngineeringString
, toPlainString, round, compareTo, getClass, notify, notifyAll, wait, wait, wait
, valueOf, valueOf, valueOf]

根据对象实现等于和==的方式,可以得到><>=<=

因此,运算符将导致已经在BigDecimal中声明的方法,或者通过groovy添加到BigDecimal中的方法被调用。它绝对不是为了能够在原语上使用操作符而对浮点这样的原始类型进行任何类型的转换。

该表取自这篇developerworks文章由Andrew和Scott撰写,该表包含更多详细信息并包含示例代码。

票数 2
EN

Stack Overflow用户

发布于 2015-05-07 13:53:37

Groovy在管理数字和实现无限精度方面做得非常出色。首先要知道的是,任何有一个点的数字在默认情况下都是一个BigDecimal --这是无限精度的原因。这里有一个例子,说明这到底意味着什么。考虑一下这个片段:

代码语言:javascript
复制
    System.out.println(2.0 - 1.1);
    System.out.println(new BigDecimal(2.0).subtract(new BigDecimal(1.1)));
    System.out.println(new BigDecimal("2.0").subtract(new BigDecimal("1.1")));

    // the above will give these:
    0.8999999999999999
    0.899999999999999911182158029987476766109466552734375
    0.9

这表明在Java中,为了获得体面的东西,我们必须经历一段时间。在Groovy中,您所要做的就是:

代码语言:javascript
复制
println 2 - 1.1​

得到你的0.9!在Groovy web控制台上试试这个。在这里,第二个操作数是一个BigDecimal,所以整个计算都是在BigDecimal中进行的,在这种情况下,精确是Groovy努力完成的目标。

但是怎么做呢?这是因为Groovy中几乎所有的操作符都映射到对隐藏对象的方法调用上,所以a+b是a.plus(b),a==b转换为a.compareTo(b)。因此,可以安全地假定您假设的内容,这是Groovy处理事情的方式:编写得更少、更有表现力,Groovy将为您完成这项工作。您可以在Groovy-lang文档页中了解所有这些,并提供所有示例。

票数 1
EN

Stack Overflow用户

发布于 2019-03-26 16:45:15

简而言之,是的,在Groovy中使用==进行BigDecimal比较是安全的。

来自Groovy文档==的行为部分:

在Java中,==意味着对象的基本类型或标识相等。在Groovy中,==翻译为a.compareTo(b)==0 (如果它们是Comparable ),而a.equals(b)则不然。要检查身份,有is。例如a.is(b)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30100856

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档