1

次のコードスニペットを検討してください-

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なのはなぜですか?整数のオーバーフローの後に取得する必要があるのは、なぜ乱数ではないのですか?
4

2 に答える 2

1

古い質問ですが、質問の両方の部分に答えようとします。

算術演算に関するGroovyのドキュメントには、次のように記載されています。

のサブクラスを含む二項演算はjava.lang.Number、次の行列に従って引数を自動的に変換します(以下で説明する除算を除く)。

行列を貼り付けませんが、演算子の1つがこれらのタイプのいずれBigIntegerかでない限り、キャストを指定しません。BigDecimal

除算の場合:

除算演算子「/」および「/=」は、いずれかのオペランドがFloatまたはDoubleの場合はDoubleの結果を生成し、それ以外の場合はBigDecimalの結果を生成します。

**Javaには存在せず、@ tim_yatesコメントで述べられているように、power実装ではデフォルトで使用されるため、このテーブルではpower演算子()は考慮されていないと思いBigIntegerます。

コードはDefaultGroovyMethods.javaint、'sの累乗が'sを使用して計算さBigIntegerれ、結果が小さい場合は再びintにキャストされることを明確に示しています(これが理由(2**4).classです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);
    }
}

他の操作の動作を確認するにはIntegerMath、、またはorg.codehaus.groovy.runtime.typehandlingパッケージLongMathの他のクラスに移動します。

于 2013-10-03T06:57:41.320 に答える
0

Groovyでは、Integer.multiply( Integer )常に整数を返します。

階乗法はステップ16のあたりでオーバーフローし始めます。

ステップ34では、最終-2147483648 * -2147483648的に0が返されるため、結果は常に0になります。

1つの修正は、メソッド宣言を次のように変更することです。

def factorial( BigInteger number ) {
于 2013-01-25T11:36:07.527 に答える