ArithmeticException Java? - PullRequest
       6

ArithmeticException Java?

1 голос
/ 27 апреля 2010

Может кто-нибудь помочь мне найти, где находится исполнение? Я не могу найти проблему ..

  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 является глобальной переменной ..

редактировать: как timeinSecs = 0? Кажется, я не могу заставить мой отладчик работать на BlackBerry JDE, так что кто-то должен будет помочь мне :( timeTaken должно быть временем в мс от момента нажатия точки запуска до точки нажатия кнопки остановки ...

все остальные переменные также являются глобальными

Ответы [ 8 ]

15 голосов
/ 27 апреля 2010

Исключения имеют типы, и это позволяет вам найти тип и быстро классифицировать проблему.Из документации:

ArithmeticException: бросается при возникновении исключительного арифметического условия.Например, целое число «делить на ноль» выбрасывает экземпляр этого класса.

Более того, большинство исключений создается с сообщением, чтобы помочь вам еще больше выяснить, что произошло.

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

Это печатает:

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

Но как это произошло?

Java, как и многие другие языки программирования, различаетцелочисленное деление и деление с плавающей запятой.

JLS 15.17.2 Оператор деления /

Бинарный оператор / выполняет деление, производя частное его операндов,Левый операнд - это дивиденд, а правый операнд - делитель.Целочисленное деление округляется до 0. [...] если значение делителя в целочисленном делении равно 0, то выдается ArithmeticException.

Следующие сведения могут вас удивить, если выне знаком с целочисленным делением:

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

Здесь происходит то, что поскольку дивиденд и делитель равны int, операция представляет собой целочисленное деление, результат которого округляется до int.Помните, что int может содержать только целое число (ограниченного диапазона, приблизительно 4 миллиарда чисел).

Вы можете указать, что вам нужно деление с плавающей запятой, сделав хотя бы один из операндов плавающей запятойчисло.

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

D - это специальный суффикс для числового литерала, указывающий, что это точное значение double.Также есть L для long (64-разрядное целое число).

Значение double необходимо сохранить в переменной double.

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

Обратите внимание, чтоделение не имеет никакого отношения к тому, к какому типу оно в итоге придет.Это зависит только от типа делимого и делителя.

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

Следует также отметить, что double также является числом с ограниченной точностью.

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

А как насчет моего кода?

Итак, теперь давайте сосредоточимся на том, что случилось с вашим кодом:

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

Скорее всего, произошло то, что timeTaken объявлен как long.Следовательно, timeTaken/1000 приводит к целочисленному делению.Если timeTaken < 1000, то результат деления будет 0.

. На этом этапе не имеет значения, является ли timeInSecs double или float, потому что целочисленное деление имеетуже было выполнено.Это означает, что timeInSecs будет 0 или 0.0, в зависимости от его типа.

По полученной ошибке можно определить, что timeInSecs может быть целочисленным типом.,В противном случае 45/timeInSecs приведет к делению с плавающей запятой, которое приведет к Infinity (специальному значению double) вместо броска ArithmeticException.

Итак, как нам исправитьthis?

Мы можем исправить это, объявив переменные следующим образом:

long timeTaken;
double timeInSecs;
double speed;

И затем выполняя вычисления следующим образом (обратите внимание, что 1000 теперьdouble значение).

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

См. Также

1 голос
/ 27 апреля 2010

Сделайте timeInSecs и speed с плавающей точкой и сделайте:

timeInSecs = (timeTaken/1000.0);
1 голос
/ 27 апреля 2010

Вероятно, прямо здесь: speed = 45/timeInSecs;

Убедитесь, что timeInSecs не равно нулю.

0 голосов
/ 27 апреля 2010

Я думаю, что, возможно, что-то не так с вычислением времени начала, и оно фактически равно времени остановки. Другая вещь может заключаться в том, что разница на самом деле выходит за пределы целого числа, вероятно, используйте long.

0 голосов
/ 27 апреля 2010

Нельзя делить на ноль, требуется дополнительная обработка ошибок для каждой части деления.

0 голосов
/ 27 апреля 2010

Похоже, что это деление на ноль в строке 6 тела метода.

0 голосов
/ 27 апреля 2010

timeInSecs - ноль.

0 голосов
/ 27 апреля 2010

45/0 времени занимает ноль, и у вас есть деление на ноль на

скорость = 45 / время в секундах;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...