【问题标题】:The range of int in JavaJava中int的范围
【发布时间】:2012-12-24 10:29:50
【问题描述】:

我了解 Java 中的 int 范围应该是 -2^31 到 2^31-1。

但是当我用 20 运行这段代码 sn-p 时:

public class Factorial {
    public int factorial(int n) {
        int fac=1;
        for (int i=1; i<=n; i++) {
            fac *= i;
            System.out.println("Factorial of " + i + " is: " + fac);
        }
        return fac;
    }
}

输出:

Factorial of 1 is: 1
Factorial of 2 is: 2
Factorial of 3 is: 6
Factorial of 4 is: 24
Factorial of 5 is: 120
Factorial of 6 is: 720
Factorial of 7 is: 5040
Factorial of 8 is: 40320
Factorial of 9 is: 362880
Factorial of 10 is: 3628800
Factorial of 11 is: 39916800
Factorial of 12 is: 479001600
Factorial of 13 is: 1932053504
Factorial of 14 is: 1278945280
Factorial of 15 is: 2004310016
Factorial of 16 is: 2004189184
Factorial of 17 is: -288522240
Factorial of 18 is: -898433024
Factorial of 19 is: 109641728
Factorial of 20 is: -2102132736

从 13 (13! = 6,227,020,800) 开始没有意义。看起来它超出了范围并被缠绕了。怎么了?是因为我使用了Eclipse吗?

虽然我觉得不相关,但这里是测试代码:

public class TestFac {

    public static void main(String[] args) {
        int n;
        Scanner sc = new Scanner(System.in);

        System.out.println("Input num you want to factorial: ");
        n = sc.nextInt();
        Factorial fac = new Factorial();
        fac.factorial(n);
    }
}

【问题讨论】:

标签: java integer range


【解决方案1】:

这里我要提一下整数时钟的概念。

Java中int的最大值和最小值是:

int MAX_VALUE = 2147483647
int MIN_VALUE = -2147483648

请检查以下结果

 int a = 2147483645;
 for(int i=0; i<10; i++) {
    System.out.println("a:" + a++);
 }

输出:

a:2147483645
a:2147483646
a:2147483647
a:-2147483648
a:-2147483647
a:-2147483646
a:-2147483645
a:-2147483644
a:-2147483643
a:-2147483642

表示当超出整数的+ve范围的限制时,下一个值又从它的负起始值开始。

 -2147483648,       <-----------------
 -2147483647,                        |
 -2147483646,                        |
  .                                  |
  .                                  |
  .                                  |    (the next value will go back in -ve range)
  0,                                 |
 +1,                                 |
 +2,                                 |
 +3,                                 |
  .                                  |
  .                                  |
  .,                                 |
 +2147483645,                        |
 +2147483646,                        |
 +2147483647     ---------------------

如果计算 13 的阶乘,则为 6227020800。 这个值超出了 java 的 int 范围。 所以新值将是

        6227020800
      - 2147483647 (+ve max value)
   -----------------
Value = 4079537153
      - 2147483648 (-ve max value)
   -----------------
value = 1932053505
   -             1  (for zero in between -ve to +ve value)
  ----------------
Answer = 1932053504

因此,在您的回答中,13 的阶乘变为 1932053504。这就是整数时钟的工作原理。

您可以使用 long 数据类型而不是整数来实现您的目的。

【讨论】:

  • long 数据类型(值大于 long MAX_VALUE)也会出现同样的问题...限制此错误 改用 BigInteger 类
  • “整数时钟”“整数的+ve范围”是什么意思
【解决方案2】:

请运行此代码:

System.out.println("Minimum value of Integer is: " + Integer.MIN_VALUE);
System.out.println("Maximum value of Integer is: " + Integer.MAX_VALUE);

所以你可以看到它失败的原因。

【讨论】:

    【解决方案3】:

    如果勾选Java Integer,其最大值和最小值如下:

    int    MAX_VALUE = 2147483647
    int    MIN_VALUE = -2147483648
    

    如果你做一些数学运算,你会发现(13 的阶乘)1932053504 * 1427048749056,它超出了 int MAX_VALUE,这就是为什么你得到 14 阶乘的错误结果。所以为了为了获得好的结果,最好改用long 类型。

    【讨论】:

      【解决方案4】:

      阶乘 13 是 6227020800。这超过 31 位长,所以它被环绕。

      如果您想支持 数字(例如,任意长度),请考虑使用提供无限范围的 BigInteger 类。

      【讨论】:

        【解决方案5】:

        来自Primitive Data Types

        int 数据类型是一个 32 位有符号二进制补码整数。它的最小值为 -2,147,483,648,最大值为 2,147,483,647(含)。对于整数值,此数据类型通常是默认选择,除非有理由(如上述)选择其他内容。这种数据类型很可能对于您的程序将使用的数字足够大,但如果您需要更大范围的值,请改用 long。

        故事的寓意:永远不要盲目相信你的老师!

        【讨论】:

        • 故事的实际寓意:仔细地听你的老师。他所说的,可能是正确的。老师给你的哪些信息是错误的?从您发布的内容来看,只有您的解释似乎是错误的。
        • 你是对的。我弄错了 10 次方和 2 次方……确实是愚蠢的错误。
        猜你喜欢
        • 1970-01-01
        • 2015-04-03
        • 2012-08-21
        • 2015-05-07
        • 1970-01-01
        • 2018-03-14
        • 1970-01-01
        • 2015-09-24
        相关资源
        最近更新 更多