1

I'm working on a small Java program, and somewhere, my calculations are going awry. My code is as follows:

import java.io.*;
import java.util.*;
import java.text.*;

public class NumManip
{

    public static void main(String args[])
    {

        Scanner numGetter = new Scanner(System.in);
        final int MULT_1 = 9;
        final int MULT_2 = 12345679;
        final int MULT_3 = 1000;
        int poorHatedNumber;

        System.out.print("Enter a digit between 1 and 9 that you dislike: ");
        poorHatedNumber = numGetter.nextInt();
        int num1 = poorHatedNumber * MULT_1, num2 = num1 * MULT_2;
        long num3 = num2 * MULT_3;

        System.out.println();

        System.out.println("           " + poorHatedNumber);
        System.out.println("          " + "x" + MULT_1);
        System.out.println("          __");
        System.out.println("          " + num1);
        System.out.println("   x" + MULT_2);
        System.out.println("          __");
        System.out.println("   " + num2);
        System.out.println("       x" + MULT_3);
        System.out.println("____________");
        System.out.println(num3);

    }

}

I've tryed printing num1, num2, and num3 on the screen to see what the problem is, and num1 is right, num2 is right, and num3 is freaky. My input is 9, and the first calculation multiplies by 9 and gets 81. Then it multiplies that by 12345679 and gets 999999999, and then it multiplies by 1000 and gets -727380968. What's wrong with that last step? I'm REALLY new to Java, and I don't get the issue.

4

4 回答 4

1

999999999 * 12345679 = 1.234567898765432e+16 远大于 anint的最大值 2,147,483,647

由于 Java 使用2-compliment 方法来存储 int 数字(意味着当数字为负数时打开最左边的位),所以这个计算“溢出”(结转)到导致负结果的那个位。

对于如此大的数字的计算,您应该使用BigDecimal

于 2013-09-22T17:12:53.517 回答
0

别担心,这真的不是一个愚蠢的错误。整个“数字通常是固定大小”——交易最初让每个人都感到困惑。既然您知道发生了什么,那就更奇怪了。这并不是您问题的真正答案,但现在您已经看到了“错误溢出”的示例,您可能会觉得这很有趣。

考虑一个奇数x。有y这样一个数字x * y == 1。这个数字y被称为模乘逆,它可以很容易地计算出来(参见 Hacker's Delight,精确除以常数)。这似乎真的违反直觉,因为它本质上允许一种奇怪的“除法”,只有当数字是除数的精确倍数时才有效,并且通常它允许您“撤消”乘以奇数的乘法。例如,如果您有a = 3 * b, 那么b = -1431655765 * a- 无论在任何一个乘法中是否有任何溢出,因此溢出不必是“破坏性的”。

于 2013-09-22T17:33:19.183 回答
0

由于 num2 和 num1 都是整数,所以发生了整数乘法,它超过了整数值的最大值。

long num3 = (long)num2 * MULT_3;
于 2013-09-22T17:13:01.530 回答
0

我认为您得到的数字大于数据类型可以处理的数字,并且随着数据类型的签名,它会环绕成负数。

于 2013-09-22T17:13:07.470 回答