当使用Java使用整数计算100(100!)的阶乘时,我得到0

2022-09-03 03:17:35

执行此操作时:

int x = 100;
int result = 1;
for (int i = 1; i < (x + 1); i++) {
    result = (result * i);
}
System.out.println(result);

这显然是因为结果对于整数来说太大了,但是我习惯于为溢出获取大负数,而不是0。

提前致谢!


当我切换到这个:

int x = 100;
int result = 1;

for (int i = 1; i < (x + 1); i++) {
    result = (result * i);
    System.out.println(result);
}

我明白


答案 1

在 1 和 100 之间有 50 个偶数(包括 1 和 100)。这意味着阶乘是至少50倍的2的倍数,换句话说,作为二进制数,最后50位将为0。(实际上它更多是因为偶数是2 * 2等的倍数)

public static void main(String... args) {
    BigInteger fact = fact(100);
    System.out.println("fact(100) = " + fact);
    System.out.println("fact(100).longValue() = " + fact.longValue());
    System.out.println("fact(100).intValue() = " + fact.intValue());
    int powerOfTwoCount = 0;
    BigInteger two = BigInteger.valueOf(2);
    while (fact.compareTo(BigInteger.ZERO) > 0 && fact.mod(two).equals(BigInteger.ZERO)) {
        powerOfTwoCount++;
        fact = fact.divide(two);
    }
    System.out.println("fact(100) powers of two = " + powerOfTwoCount);
}

private static BigInteger fact(long n) {
    BigInteger result = BigInteger.ONE;
    for (long i = 2; i <= n; i++)
        result = result.multiply(BigInteger.valueOf(i));
    return result;
}

指纹

fact(100) = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
fact(100).longValue() = 0
fact(100).intValue() = 0
fact(100) powers of two = 97

这意味着 97 位整数对于事实的最低位为 0(100)

事实上,对于 fact(n),二的幂数非常接近 n。事实上(10000)有9995次幂的2。这是因为它大约是 n 次 1/2 的幂之和,得到的总数接近 。即,每秒钟的数字是偶数n / 2,每个4th具有2的附加幂(+n / 4),并且每个8th具有额外的幂(+n / 8)等接近总和。nn


答案 2

大负数是溢出到某些范围的值; 末尾有超过 32 个二进制零,因此将其转换为整数将产生零。factorial(100)


推荐