Java 算术异常?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2717032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 12:02:46  来源:igfitidea点击:

ArithmeticException Java?

java

提问by KP65

Can anyone help me find where the execption is? I can't seem to find the problem..

谁能帮我找到 execption 在哪里?好像找不到问题。。

  public void fieldChanged(Field f, int context){
        //if the submit button is clicked
     try{
      stopTime = System.currentTimeMillis();
      timeTaken = stopTime - startTime;
      timeInSecs = ((timeTaken/1000));
      speed = 45/timeInSecs;
      Dialog.alert("Speed of Delivery: " + speed + "mph");
      }
     catch(ArithmeticException e){
      Dialog.alert("error " + speed);
      e.printStackTrace();

     }

    } 

startTime variable is a global variable..

startTime 变量是一个全局变量..

edit: how can timeinSecs = 0? I cant seem to get my debugger working for the BlackBerry JDE so someone will have to help me out :( timeTaken should be the time in ms from pushing the point of pushing a start button to the pont of pushing the stop button...

编辑:timeinSecs = 0 怎么可能?我似乎无法让我的调试器为 BlackBerry JDE 工作,所以有人必须帮助我:( timeTaken 应该是从按下开始按钮到按下停止按钮的时间,以毫秒为单位......

all other variables are global as well

所有其他变量也是全局变量

采纳答案by polygenelubricants

Exceptions have types, and what this allows is for you to look up the type and quickly categorize the problem. From the documentation:

异常有类型,这允许您查找类型并快速分类问题。从文档:

ArithmeticException: Thrown when an exceptional arithmetic condition has occurred. For example, an integer "divide by zero" throws an instance of this class.

ArithmeticException:发生异常算术条件时抛出。例如,整数“除以零”抛出此类的一个实例。

Moreover, most exceptions are constructed with a message to help you even further figure out what happened.

此外,大多数异常都带有一条消息,以帮助您进一步弄清楚发生了什么。

try {
    int i = 0 / 0;
} catch (ArithmeticException e) {
    e.printStackTrace();
}

This prints:

这打印:

java.lang.ArithmeticException: / by zero
    at [filename:line number]

But how did this happen?

但这是怎么发生的呢?

Java, like many other programming languages, distinguishes between integer division and floating point division.

与许多其他编程语言一样,Java 区分整数除法和浮点除法。

JLS 15.17.2 Division Operator /

JLS 15.17.2 分区运算符 /

The binary /operator performs division, producing the quotient of its operands. The left-hand operand is the dividend and the right-hand operand is the divisor. Integer division rounds toward 0. [...] if the value of the divisor in an integer division is 0, then an ArithmeticExceptionis thrown.

二元/运算符执行除法,产生其操作数的商。左边的操作数是被除数,右边的操作数是除数。整数除法向 0 舍入。 [...] 如果整数除法中的除数值为 0,则ArithmeticException抛出an 。

The following may surprise you if you're not familiar with integer division:

如果您不熟悉整数除法,以下内容可能会让您感到惊讶:

    System.out.println(1/2); // prints "0"

What happens here is that since both the dividend and the divisor are int, the operation is an integer division, whose result is rounded to an int. Remember that an intcan only contain whole number (of limited range, some 4 billion numbers approximately).

这里发生的情况是,由于被除数和除数都是int,因此运算是整数除法,其结果四舍五入为int。请记住,一个int只能包含整数(范围有限,大约有 40 亿个数字)。

You can specify that you need a floating point division by making at least one of the operands a floating point number.

您可以通过将至少一个操作数设为浮点数来指定需要进行浮点除法。

    System.out.println(1/2.0); // prints "0.5"
    System.out.println(1D/2); // prints "0.5"

Dis a special suffix for numeric literal to specify that it's a double-precision value. There's also Lfor long(64-bit integer).

D是数字文字的特殊后缀,用于指定它是一个double-precision 值。还有Lfor long(64 位整数)。

A doublevalue needs to be stored in a doublevariable.

double值需要被存储在一个double变量中。

    double v = 1D / 2; // v == 0.5
    int i = 1D / 2; // DOESN'T COMPILE!!! Explicit cast needed!

Note that which division is performed doesn't have anything to do with what type it'll eventually go to. It only depends on what type the dividend and divisor are.

请注意,执行哪个除法与它最终会转到什么类型没有任何关系。这仅取决于被除数和除数是什么类型。

    double v = 1 / 2; // v == 0.0 (!!!)

You should also note that doubletoo, is a limited precision number.

您还应该注意,它double也是一个有限精度的数字。

    System.out.println(.2D + .7D - .9D); // prints "-1.1102230246251565E-16"

But what about my code?

但是我的代码呢?

So now, let's focus on what happened with your code:

现在,让我们关注您的代码发生了什么:

  timeTaken = stopTime - startTime;
  timeInSecs = ((timeTaken/1000));
  speed = 45/timeInSecs;

More than likely what happened is that timeTakenis declared as a long. Therefore timeTaken/1000results in integer division. If timeTaken < 1000, the result of the division is 0.

发生的事情很可能timeTaken被声明为long. 因此timeTaken/1000导致整数除法。如果timeTaken < 1000,除法的结果是0

At this point, it doesn't matter if timeInSecsis a doubleor a float, because the integer division has already been performed. This means that timeInSecswould be either 0or 0.0, depending on its type.

此时,无论timeInSecs是 adouble还是 a都没有关系float,因为已经执行了整数除法。这意味着它timeInSecs可以是00.0,具体取决于其类型。

From the error you get, though, one can determine that timeInSecsis likely to be an integer type. Otherwise, 45/timeInSecswould result in a floating point division that results in Infinity(a special doublevalue) instead of throwing ArithmeticException.

但是,从您得到的错误中,可以确定它timeInSecs可能是整数类型。否则,45/timeInSecs将导致浮点除法导致Infinity(特殊double值)而不是抛出ArithmeticException

So how do we fix this?

那么我们如何解决这个问题呢?

We can fix this by declaring the variables as follows:

我们可以通过如下声明变量来解决这个问题:

long timeTaken;
double timeInSecs;
double speed;

And then performing the calculation as follows (note that 1000is now a doublevalue).

然后执行如下计算(注意1000现在是一个double值)。

timeTaken = stopTime - startTime;
timeInSecs = timeTaken/1000D;
speed = 45D/timeInSecs; // D is not necessary here, but it's good for clarity

See also

也可以看看

回答by bitc

Probably right here: speed = 45/timeInSecs;

大概就在这里: speed = 45/timeInSecs;

Make sure that timeInSecs is not zero.

确保 timeInSecs 不为零。

回答by James

45 / 0 time taken reaches zero and you have division by zero at

45 / 0 所用时间达到零,并且您在

speed = 45/timeInSecs;

速度 = 45/timeInSecs;

回答by SLaks

timeInSecsis zero.

timeInSecs为零。

回答by Eyal Schneider

Seems like this is a division by zero in line 6 of the method body.

似乎这是方法主体第 6 行中的除以零。

回答by Matthew Flaschen

Make timeInSecsand speedfloats, and do:

制作timeInSecsspeed浮动,并执行:

timeInSecs = (timeTaken/1000.0);

回答by vaske

You can't divide with zero, need extra error handling on every divide part.

您不能除以零,需要对每个除法部分进行额外的错误处理。

回答by Boolean

I think there is probably something wrong with startime calculation and it is actually equal to stoptime. Other thing could be the difference is actually going beyond the limit of the integer, probably use a long.

我认为 starttime 计算可能有问题,它实际上等于 stoptime。另一件事可能是差异实际上超出了整数的限制,可能使用了long。