Почему деление на ноль с плавающей запятой (или двойной точностью) числа не бросают java.ленг.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 (не число) без исключение.

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

6 ответов


короче говоря, так это указано в стандарте IEEE-754, который является тем, что Java Операции С Плавающей Запятой основаны на.

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

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

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

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


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

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

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

создание исключения похоже на (программное обеспечение) INT создается делением на ноль на x86 микропроцессоры.


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

class DoubleDivision {

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

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

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

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

Также см. раздел : Специальные Значения С Плавающей Запятой at Математические Ошибки дополнительные info:)

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

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


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

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

для целых значений с использованием common двойки-схема дополнения (как требует Java), все 32-битные (для int) и 64-битных (для long) битовые шаблоны представляют собой количество. Таким образом, компьютер не может сообщить о проблеме с помощью sentinel. Он должен каким-то образом сообщать о проблеме "вне диапазона". Исключение-это метод out of band, выбранный для Java.


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

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


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 */