类型推广如何在Groovy中运行?

时间:2013-01-25 10:57:09

标签: groovy

请考虑以下代码段 -

def factorial(number) {
    if(number == 1)
        return number;
    else 
        return number * factorial(number - 1);
}

println factorial(50)
println factorial(50).getClass()

println()

println 45**20
println ((45**20).getClass())

输出是 -

0
class java.lang.Integer

1159445329576199417209625244140625
class java.math.BigInteger

问题 -

  1. 为什么在第一种情况下,groovy不会自动将number * factorial(number-1)的结果提升为BigInt
  2. 为什么输出0?为什么在整数溢出后我们应该得到一些随机数?

2 个答案:

答案 0 :(得分:1)

旧问题,但我会尝试回答问题的两个部分:

Groovy documentation on arithmetic operations表示

  
    

涉及java.lang.Number子类的二进制操作会根据以下矩阵自动转换它们的参数(除了除法,这将在下面讨论)

  

我不会粘贴矩阵,但它不会向BigIntegerBigDecimal指定任何转换,除非其中一个运算符属​​于这些类型之一。

在分割的情况下:

  
    

如果操作数是Float或Double,则除法运算符“/”和“/ =”产生Double结果,否则产生BigDecimal结果

  

我认为该表未考虑幂运算符(**),因为它不存在于Java中,并且如@tim_yates注释中所述,power实现默认使用BigInteger

code in DefaultGroovyMethods.java清楚地表明int的力量是使用BigInteger来计算的,如果结果很小则会再次转换为int(这就是为什么{ {1}}是(2**4).class):

java.lang.Integer

要确认其他操作的行为,您可以转到IntegerMathLongMathorg.codehaus.groovy.runtime.typehandling package

中的其他课程

答案 1 :(得分:0)

使用Groovy,Integer.multiply( Integer )总是返回一个整数。

阶乘方法在第16步开始溢出。

在步骤34,您最终得到-2147483648 * -2147483648,返回0,因此结果将始终为0

一种解决方法是将方法声明更改为:

def factorial( BigInteger number ) {