使用double
值时,我有点困惑。
当我使用如下: -
double foo = 20.46455
assert 20 == foo.round()
assert 20.46 == foo.round(2)
工作正常。但是当我使用像: -
这样的东西时def foo = 20.46455
assert 20 == foo.round()
抛出: -
显示java.lang.NullPointerException
和
def foo = 20.46455
assert 20.46 == foo.round(2)
抛出: -
groovy.lang.MissingMethodException:没有方法签名:java.math.BigDecimal.round()适用于参数类型:(java.lang.Integer)值:[2] 可能的解决方案:round(java.math.MathContext),find(),pow(int),power(java.lang.Integer),find(groovy.lang.Closure)和(java.lang.Number)
默认情况下,这意味着groovy
,BigDecimal
中的值保留,BigDecimal.round()
期望java.math.MathContext
作为输入。
但是,当我使用除double
之外的Math.round()
作为输入时,我的混淆就开始了,然后为什么在BigDecimal
?
def foo = 20.46455
assert 20 == Math.round(foo)
为什么我必须使用.toDouble()
来传递我的测试用例,foo
具有double
格式的值,如下所示?
def foo = 20.46455
assert 20 == foo.toDouble().round()
assert 20.46 == foo.toDouble().round(2)
注意: - 我不想知道如何round
一个double值,我只是想知道为什么groovy
在每种情况下表现不同?< / p>
答案 0 :(得分:6)
除非您定义类型或为数字添加后缀(如D),否则Groovy会自动并隐式地将BigDecimal用于任何浮点数。
<强>示例:强>
def foo = 20.46455
println foo.getClass()
输出
class java.math.BigDecimal
double foo = 20.45645
println foo.getClass()
输出
class java.lang.Double
def foo = 20.45645d
println foo.getClass()
输出
class java.lang.Double
输入转化次数
Groovy也有一些自动类型转换,这就是为什么Math.round()
只接受double
和float
原语作为参数的原因,当你传递BigDecimal时代码没有失败。为了证明这一点,您可以实现自己的round
函数并检查类型转换会发生什么:
<强>示例:强>
def round(double foo) {
println foo.getClass()
return foo.round()
}
def foo = 20.46455
println foo.getClass()
assert 20 == round(foo)
<强>输出:强>
class java.math.BigDecimal
class java.lang.Double
隐式转换的一些更有效的例子:
def round(float foo) {
println foo.getClass()
return foo.round()
}
def foo = 20.46455
println foo.getClass()
assert 20 == round(foo)
<强>输出:强>
class java.math.BigDecimal
class java.lang.Float
def round(float foo) {
println foo.getClass()
return foo.round()
}
def foo = 20
println foo.getClass()
assert 20 == round(foo)
<强>输出:强>
class java.lang.Integer
class java.lang.Float
def round(double foo) {
println foo.getClass()
return foo.round()
}
def foo = 20
println foo.getClass()
assert 20 == round(foo)
<强>输出:强>
class java.lang.Integer
class java.lang.Double
def round(BigDecimal foo) {
println foo.getClass()
return foo
}
double foo = 20.0
println foo.getClass()
assert 20 == round(foo)
的输出:强>
class java.lang.Double
class java.lang.BigDecimal
根据经验,如果数字是基于浮点的(double
,float
,BigDecimal
),则彼此之间将存在隐式类型转换,代码将尝试转换为非浮点数时抛出异常(例如int
或long
)。如果数字不是浮点类型(int
,long
),则可以在非浮点类型和浮点类型之间进行转换,因为浮点数也包括非浮点类型作为子集(例如,1可以用1.0表示。这是有道理的,因为你不能将浮点信息从float传递给int(20.5不能用int
变量表示),但在大多数情况下你可以做相反的事情,偶尔大值溢出的例外(例如,long
变量中的float
数字非常大。)