Java简单算法的问题

时间:2013-09-22 17:09:45

标签: java

我正在开发一个小型Java程序,在某个地方,我的计算出错了。我的代码如下:

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);

    }

}

我尝试在屏幕上打印num1,num2和num3以查看问题所在,而num1是正确的,num2是正确的,而num3是怪异的。我的输入是9,第一次计算乘以9得到81.然后它乘以12345679得到999999999,然后它乘以1000得到-727380968。最后一步出了什么问题?我真的是Java的新手,我没有遇到这个问题。

4 个答案:

答案 0 :(得分:1)

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

由于Java使用2-compliment method to store int number(意味着当数字为负时最左边的位被打开),这个计算“溢出”(残留)到该位,导致负面结果。

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

答案 1 :(得分:0)

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

long num3 = (long)num2 * MULT_3;

答案 2 :(得分:0)

我认为你得到的数字大于数据类型可以处理的数字,并且当数据类型被签名时,它会包含在负数中。

答案 3 :(得分:0)

别担心,这真的不是一个愚蠢的错误。整个“数字通常是一个固定的大小” - 最初只会让每个人感到困惑。现在你知道了什么,这里甚至更奇怪。这不是你的问题的答案,但是现在你刚刚看到一个“糟糕的溢出”的例子,你可能会觉得这很有趣。

考虑一个奇数x。有一个yx * y == 1。这个数字y被称为modular multiplicative inverse,它可以很容易地计算出来(参见Hacker's Delight,精确除以常数)。这看起来可能是非常直观的,因为它实际上允许一种奇怪的类型“除法”,只有在数字是除数的精确倍数时才有效,并且通常它允许您“乘以”奇数的乘法。例如,如果你有a = 3 * b,那么b = -1431655765 * a - 无论乘法是否有任何溢出,所以溢出不一定是“破坏性的”。