Почему деление на ноль с номерами с плавающей запятой (или двойной точностью) не вызывает java.lang.ArithmeticException:/на ноль в Java

Следующий оператор бросает java.lang.ArithmeticException: / by zero как очевидный.

System.out.println(0/0);

потому что литерал 0 считается литералом int и деление на ноль не допускается в целочисленной арифметике.

Следующий случай, однако не выполняет исключение, например java.lang.ArithmeticException: / by zero.

int a = 0;
double b = 6.199;
System.out.println((b/a));

Отображается Infinity.

Следующий оператор создает NaN (Not a Number) без исключения.

System.out.println(0D/0); //or 0.0/0, or 0.0/0.0 or 0/0.0 - floating point arithmetic.

В этом случае оба операнда считаются двойными.


Аналогично, следующие операторы не делают исключение.

double div1 = 0D/0; //or 0D/0D
double div2 = 0/0D; //or 0D/0D

System.out.printf("div1 = %s : div2 = %s%n", div1, div2);
System.out.printf("div1 == div2 : %b%n", div1 == div2);
System.out.printf("div1 == div1 : %b%n", div1 == div1);
System.out.printf("div2 == div2 : %b%n", div2 == div2);
System.out.printf("Double.NaN == Double.NaN : %b%n", Double.NaN == Double.NaN);
System.out.printf("Float.NaN == Float.NaN : %b%n", Float.NaN == Float.NaN);

Они производят следующий вывод.

div1 = NaN : div2 = NaN
div1 == div2 : false
div1 == div1 : false
div2 == div2 : false
Double.NaN == Double.NaN : false
Float.NaN == Float.NaN : false

Все они возвращаются false. Почему эта операция (деление на ноль) разрешена с номерами с плавающей запятой или двойной точностью?


Кстати, я могу понять, что числа с плавающей запятой (числа двойной точности) имеют свои значения, которые представляют собой положительную бесконечность, отрицательную бесконечность, а не число (NaN)...

Ответ 1

Короче говоря, тот способ, который он специфицировал в стандарте IEEE-754, который представляет собой Java Операции с плавающей запятой, основан на.

Почему не деление на ноль (или переполнение или недополнение) останавливает программу или вызывает ошибку? Почему стандарт по номерам включает "not-a-number" (NaN)?

Модель 754 поощряет надежные программы. Он предназначен не только для численных аналитиков, но и для пользователей электронных таблиц, систем баз данных или даже кофейников. Правила распространения для NaNs и бесконечностей допускают неосуществимые исключения для обращения в нуль. Аналогичным образом, постепенное недополнение поддерживает свойства ошибки в прецизионном диапазоне.

Когда исключительные ситуации требуют внимания, они могут быть немедленно проверены через ловушки или в удобное время через флаги состояния. Ловушки могут использоваться для остановки программы, но неустранимые ситуации крайне редки. Простота остановки программы не является вариантом для встроенных систем или сетевых агентов. Чаще всего ловушки регистрируют диагностическую информацию или заменяют действительные результаты.

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

Ответ 2

Это так, потому что это определило IEEE 754.

Подразделение с плавающей точкой 0.0 дает NaN или +/- Inf, в зависимости от того, является ли числитель 0 или нет.

Разделение на целое число 0 не распространяется на IEEE 754 и генерирует исключение - нет другого способа указания ошибки, поскольку int не может представлять NaN или Inf.

Генерация исключения аналогична (программному обеспечению) int, генерируемому делением на ноль на микропроцессорах x86.

Ответ 3

В бесконечность и дальше

class DoubleDivision {

    public static void main(String[] args) {
        System.out.println(5.0/0.0);
    }
}

Приведенный выше код и приведенные фрагменты дают infinity.

Почему Java использует Double для представления десятичных знаков. Двоичный не может полностью представить число, он может представлять только приближение, и поэтому Javas не может удвоиться.

Представьте себе число, невероятно близкое к нулю. Если вы знаете исчисление, представьте себе предел в ноль. Переменная будет приближаться к нулю до некоторого воображаемого крошечного расстояния, но никогда точно не будет равна. Вы можете себе это представить, верно? Ну, предположим, что для числа требуется так много точности для представления Java, он отказывается и называет его 0.0, потому что у него нет хорошей альтернативы. То, что здесь происходит. Любое регулярное число, деленное на супер близкое число к нулю, в основном, бесконечность. Попробуйте: 5 / (10^-100).

Также см. раздел: Специальные значения с плавающей запятой Math Errors для получения дополнительной информации:)

Связанный вопрос: почему 1/0 дает ошибку, но 1.0/0/0 дает inf

UPDATE: INT не имеет бесконечности и NaN значение в наборе, тогда как float имеет бесконечность и значение NaN. (Согласно стандартам IEEE 754, которые соответствуют java)

Ответ 4

Когда есть деление на ноль, компьютер не может создать представление результата в виде числа. Компьютер должен сигнализировать, что результат не является числом.

Для значений с плавающей запятой он может выдавать специальное значение нечётного числа, поскольку существуют 32-битные (для float) и 64-разрядных (для double) битовые шаблоны, которые не представляют собой число и, следовательно, может быть интерпретировано как не-число (NaN).

Для целочисленных значений, использующих общую схему двойного дополнения (как требуется Java), все 32-битные (для int) и 64-битные (для long) битовые шаблоны представляют собой число. Поэтому компьютер не может сообщить о проблеме с помощью дозорного устройства. Он должен каким-то образом сообщать о проблеме "вне диапазона". Выбрасывание исключения - это метод вне диапазона, выбранный для Java.

Ответ 5

Java следует стандарту IEEE 754, который определяет значения для возврата по умолчанию в случае деления на ноль. http://en.wikipedia.org/wiki/IEEE_754#Exception_handling

Деление на ноль (операция с конечными операндами дает точный бесконечный результат, например, 1/0 или log (0)) (по умолчанию возвращает ± бесконечность).

Ответ 6

import java.util.Scanner;

public class Division {

    public static void main(String[] args) {
        int a, b;
        float result;

        Scanner input = new Scanner(System.in);
        System.out.println("Enter value for a : ");
        a = input.nextInt();

        System.out.println("Enter value for b : ");
        b = input.nextInt();

        try {
            /* here we used "if clause" because result will be in float
             note: Here result is in float, so JVM Cant Catch Exception.
             if we Try to Divide with Zero with Float Values It gives Output as
             Divided by Zero is Infinity */
            if (b != 0) {
                result = (float) a / b;
                System.out.println("Result of " + a + " divided by " + b + " is : " + result);
            } else // here result will be in integer so Jvm can easily Catch The Exception
            {
                result = a / b;
            }
        } catch (ArithmeticException e) {
            System.out.println("Sorry Division By Zero Is Not Possible");
        }
    }
}

/* Ouput :
Enter value for a :2
Enter value for b : 7
Result of 2 divided by 7 is : 0.2857143 */

 /* Ouput :
Enter value for a : 16
Enter value for b : 0
Sorry Division By Zero Is Not Possible */