Почему Java не генерирует исключение при делении на 0.0? - PullRequest
67 голосов
/ 04 марта 2010

У меня есть код для расчета процентной разницы между 2 числами - (oldNum - newNum) / oldNum * 100; - где оба числа double s. Я ожидал добавить какую-то обработку проверки / исключения в случае, если oldNum равен 0. Однако когда я выполнил тестовый запуск со значениями 0.0 для oldNum и newNum, выполнение продолжилось, как будто ничего не произошло, и не было выдано никакой ошибки. Запуск этого кода с int s определенно вызвал бы арифметическое исключение деления на ноль. Почему Java игнорирует это, когда дело доходит до double s?

Ответы [ 5 ]

110 голосов
/ 04 марта 2010

Java float и double типы, как и почти любой другой язык (и почти любой аппаратный модуль FP), реализуют стандарт IEEE 754 для математики с плавающей запятой, который требует разделения на ноль, чтобы вернуть специальное значение "бесконечность". Бросок исключения фактически нарушает этот стандарт.

Целочисленная арифметика (реализованная в виде дополнения до двух представление Java и большинством других языков и аппаратного обеспечения) отличается и не имеет специальных значений бесконечности или NaN, поэтому использование исключений является полезным поведением.

45 голосов
/ 04 марта 2010

Результат деления на ноль, математически говоря, undefined , который можно выразить с помощью числа с плавающей запятой / двойного (как NaN - не число), однако это не так в каком-то фундаментальном смысле.

Поскольку целое число должно содержать определенное числовое значение, при работе с ними должна возникать ошибка при делении на ноль.

5 голосов
/ 04 марта 2010

Способ хранения двойника совершенно отличается от типа int.См. http://firstclassthoughts.co.uk/java/traps/java_double_traps.html для более подробного объяснения того, как Java обрабатывает двойные вычисления.Вам также следует ознакомиться с числами с плавающей точкой, в частности с понятием Не число (NaN) .

Если вам интересно узнать больше о представлении с плавающей точкой, я бы посоветовал прочитать этот документ (формат Word, извините).Он углубляется в двоичное представление чисел, что может быть полезно для вашего понимания.

4 голосов
/ 01 октября 2017

При делении на ноль (0 или 0,00)

  1. Если вы разделите double на 0, JVM покажет Infinity .

    public static void main(String [] args){ double a=10.00; System.out.println(a/0); }

    Консоль: Infinity

  2. Если вы поделите int на 0, JVM выдаст Арифметическое исключение .

    public static void main(String [] args){ int a=10; System.out.println(a/0); }

    Консоль: Exception in thread "main" java.lang.ArithmeticException: / by zero

  3. Но если мы разделим int на 0.0, то JVM покажет бесконечность:

    public static void main(String [] args){ int a=10; System.out.println(a/0.0); }

    Консоль: Infinity

Это потому, что JVM автоматически наберет приведение типа int к double, поэтому мы получаем бесконечность вместо ArithmeticException.

4 голосов
/ 02 февраля 2016

Хотя Java-разработчики знают о типе двойного примитива и классе Double, при выполнении арифметики с плавающей запятой они не уделяют достаточного внимания Double.INFINITY, NaN, -0.0 и другим правилам, которые управляют арифметическими вычислениями с участием их.

Простой ответ на этот вопрос заключается в том, что он не выбросит ArithmeticException и вернет Double.INFINITY. Также обратите внимание, что сравнение x == Double.NaN всегда оценивается как false, даже если само x является NaN.

Чтобы проверить, является ли x NaN, следует использовать вызов метода Double.isNaN(x), чтобы проверить, является ли данное число NaN или нет. Это очень близко к NULL в SQL.

Это может быть полезно для вас.

...