Reputation: 18607
Consider the following code snippet -
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())
The output is -
0
class java.lang.Integer
1159445329576199417209625244140625
class java.math.BigInteger
Questions -
number * factorial(number-1)
to a BigInt
in the first case?Upvotes: 1
Views: 185
Reputation: 7344
Old question but I'll try to answer both parts of the question:
Groovy documentation on arithmetic operations states that
binary operations involving subclasses of
java.lang.Number
automatically convert their arguments according to the following matrix (except for division, which is discussed below)
I won't paste the matrix but it specifies no casting to BigInteger
or BigDecimal
unless one of the operators is of one of these types.
In the case of division:
The division operators "/" and "/=" produce a Double result if either operand is either Float or Double and a BigDecimal result otherwise
I think that the table is not considering the power operator (**
) since it's not present in Java and as stated in @tim_yates comment, power
implementation uses BigInteger
by default.
The code in DefaultGroovyMethods.java
shows clearly that the power of int
's is calculated using BigInteger
's and if the result is small then is cast down to int again (And that's why (2**4).class
is java.lang.Integer
):
public static Number power(Integer self, Integer exponent) {
if (exponent >= 0) {
BigInteger answer = BigInteger.valueOf(self).pow(exponent);
if (answer.compareTo(BI_INT_MIN) >= 0 && answer.compareTo(BI_INT_MAX) <= 0) {
return answer.intValue();
} else {
return answer;
}
} else {
return power(self, (double) exponent);
}
}
To confirm the behaviour of other operations you can go to IntegerMath
, LongMath
or other classes in the org.codehaus.groovy.runtime.typehandling package
Upvotes: 1
Reputation: 171114
With Groovy, Integer.multiply( Integer )
always returns an Integer.
The factorial method starts overflowing around step 16.
At step 34, you end up with -2147483648 * -2147483648
which returns 0 so the result will always be 0
One fix is to change your method declaration to:
def factorial( BigInteger number ) {
Upvotes: 0