简体   繁体   English

为什么我的析因程序打印为0?

[英]Why does my factorial program print 0?

This code is meant to find 100 factorial and the sum the digits in the number. 该代码用于查找100阶乘,然后将数字中的数字相加。 However, it returns 0. 但是,它返回0。

Why does this happen? 为什么会这样?

public class Problem20 {
  public static void main(String[] args){
    int num = 100;

    for(int i = 1; i< 100; i++){
        num = num * i;
    }

    String numstring = Integer.toString(num);
    int sum = 0;

    for(int j = 0; j < numstring.length(); j++){
        sum += numstring.charAt(j) - '0';
    }
    System.out.print(sum);
  }
}

Every time you multiply by 2, you add a 0 to the low bits of binary representation of the number. 每次乘以2,就会在数字的二进制表示形式的低位添加一个0

According to the JLS §15.17.1 : 根据JLS§15.17.1

If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format. 如果整数乘法溢出,则结果是数学乘积的低阶位 ,以某种足够大的二进制补码格式表示。 As a result, if overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two operand values. 结果,如果发生溢出,则结果的符号可能与两个操作数值的数学乘积的符号不同。

Here's some code to demonstrate this point. 这是一些代码来证明这一点。 As you can see, the number of 0 at the end of the number slowly increases; 如您所见,数字结尾处的数字0缓慢增加; soon as we get to 32, the low order bits become all 0. See: Why does this multiplication integer overflow result in zero? 一到32,低阶位就全部变为0。请参阅: 为什么这个乘法整数溢出会导致零?

public class Problem20 {
  public static void main(String[] args) {
    int num = 100;

    for (int i = 1; i < 33; i++) {
      num = num * i;
      System.out.println(i + "\t" + Integer.toBinaryString(num));
    }
  }
}

Output: 输出:

1   1100100
2   11001000
3   1001011000
4   100101100000
5   10111011100000
6   10001100101000000
7   1111011000011000000
8   1111011000011000000000
9   10001010011011011000000000
10  10101101000010001110000000000
11  11101101111011000011010000000000
12  100111000100100111000000000000
13  11111011111011111011000000000000
14  11000111000110111010000000000000
15  10101010100111100110000000000000
16  10101001111001100000000000000000
17  1001000010001100000000000000000
18  10100111011000000000000000000
19  10001101100001000000000000000000
20  1110010100000000000000000000
21  101100100100000000000000000000
22  11010100011000000000000000000000
23  10100101000000000000000000000
24  11101111000000000000000000000000
25  1010111000000000000000000000000
26  11010110000000000000000000000000
27  10010010000000000000000000000000
28  11111000000000000000000000000000
29  11000000000000000000000000000
30  11010000000000000000000000000000
31  110000000000000000000000000000
32  0

You can solve this problem by using BigInteger instead of int , eg 您可以通过使用BigInteger而不是int来解决此问题,例如

import java.math.BigInteger;

public class Problem20 {
  public static void main(String[] args) {
    BigInteger num = BigInteger.valueOf(100);

    for (int i = 1; i < 100; i++) {
      num = num.multiply(BigInteger.valueOf(i));
      System.out.println(num);
    }
  }
}

Alright. 好的。

1! = 1
2! = 2
3! = 6
4! = 24
.
.
.
10! = 3628800
.
.
100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

Do you think this fits in any of those data-types? 您认为这适合任何这些数据类型吗?

What happens once a number crosses the limit? 一旦数字超过限制会怎样? It overflows. 它溢出了。 And hence you get a wrong answer. 因此,您会得到错误的答案。

So what do I do? 那我该怎么办?

Use BigInteger . 使用BigInteger

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM