Groovy中的类型提升是如何工作的?

Groovy中的类型提升是如何工作的?,groovy,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())

考虑以下代码片段-

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
问题-

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

  • 对于Groovy,
    Integer.multiply(Integer)
    总是返回一个整数

    阶乘方法在步骤16左右开始溢出

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

    一种修复方法是将方法声明更改为:

    def factorial( BigInteger number ) {
    

    对于Groovy,
    Integer.multiply(Integer)
    总是返回一个整数

    阶乘方法在步骤16左右开始溢出

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

    一种修复方法是将方法声明更改为:

    def factorial( BigInteger number ) {
    

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

    声明

    涉及
    java.lang.Number
    子类的二进制操作会根据以下矩阵自动转换其参数(除法除外,如下所述)

    我不会粘贴矩阵,但它指定不强制转换为
    biginger
    BigDecimal
    ,除非其中一个运算符属于这些类型之一

    在除名的情况下:

    如果任一操作数为浮点或双精度,则除法运算符“/”和“/”生成双精度结果,否则生成BigDecimal结果

    我认为该表没有考虑power操作符(
    ***
    ),因为它在Java中不存在,正如@tim_yates注释中所述,
    power
    实现默认使用
    biginger

    这清楚地表明,
    int
    的幂是使用
    biginger
    计算的,如果结果很小,则再次向下转换为int(这就是为什么
    (2**4)。类是
    java.lang.Integer
    ):

    公共静态数字幂(整数自身,整数指数){
    如果(指数>=0){
    BigInteger answer=BigInteger.valueOf(self).pow(指数);
    
    如果(answer.compareTo(BI_INT_MIN)>=0&&answer.compareTo(BI_INT_MAX)这是一个老问题,但我将尝试回答问题的两个部分:

    声明

    涉及
    java.lang.Number
    子类的二进制操作会根据以下矩阵自动转换其参数(除法除外,如下所述)

    我不会粘贴矩阵,但它指定不强制转换为
    biginger
    BigDecimal
    ,除非其中一个运算符属于这些类型之一

    在除名的情况下:

    如果任一操作数为浮点或双精度,则除法运算符“/”和“/”生成双精度结果,否则生成BigDecimal结果

    我认为该表没有考虑power操作符(
    ***
    ),因为它在Java中不存在,正如@tim_yates注释中所述,
    power
    实现默认使用
    biginger

    这清楚地表明,
    int
    的幂是使用
    biginger
    计算的,如果结果很小,则再次向下转换为int(这就是为什么
    (2**4)。类是
    java.lang.Integer
    ):

    公共静态数字幂(整数自身,整数指数){
    如果(指数>=0){
    BigInteger answer=BigInteger.valueOf(self).pow(指数);
    
    如果(answer.compareTo(BI_INT_MIN)>=0&&answer.compareTo(BI_INT_MAX),另一个修复将是
    阶乘(50G)
    。但是我很困惑,如果
    **
    10**4
    是整数,
    10**45
    是BigInt,怎么会自动升级到BigInt。如果溢出,是否会自动升级类型?为什么不能对
    *
    执行同样的操作?--groovydocs状态“整数对某个指数的幂。如果指数为正,则转换为BigInteger并调用BigInteger.pow(int)方法以保持精度。由'**'运算符调用。”所以求幂的结果应始终为BigInt。对吗?那么为什么
    打印((2**4).getClass()
    print
    java.lang.Integer
    。另一个修复方法是
    factorial(50G)
    。但是我很困惑,如果
    **
    10**4
    是整数,
    10**45
    是BigInt,怎么会自动升级到BigInt。如果溢出,是否会自动升级类型?为什么不能对
    *
    执行同样的操作?--groovydocs状态“整数对某个指数的整数的幂。如果指数为正,则转换为BigInteger并调用BigInteger.pow(int)方法以保持精度。由“**”运算符调用。“因此,求幂的结果应始终为BigInt。对吗?那么为什么
    打印((2**4).getClass())
    print
    java.lang.Integer
    。很抱歉直到今天我才看到这个答案。+1因为我指向了实际的来源。我很抱歉直到今天我才看到这个答案。+1因为我指向了实际的来源。