Почему целочисленное деление на ноль 1/0 дает ошибку, а плавающая точка 1 / 0.0 возвращает «Inf»? - PullRequest
27 голосов
/ 13 марта 2011

Мне просто любопытно:

При оценке 1/0 в Java возникает следующее исключение:

Исключение в теме "главная" java.lang.ArithmeticException: / by нуль в Foo.main (Foo.java:3)

Но 1/0.0 оценивается как Infinity.

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

Почему это происходит?

Ответы [ 5 ]

30 голосов
/ 13 марта 2011

Это потому, что целые числа не имеют значений +/- Inf, NaN и не допускают деление на 0, в то время как числа с плавающей запятой имеют эти специальные значения.

11 голосов
/ 13 марта 2011

1/0 - это деление двух int s, которое выдает исключение, потому что вы не можете делить на целое ноль. Однако 0.0 является литералом типа double , и Java будет использовать деление с плавающей запятой. Спецификация IEEE с плавающей запятой имеет специальные значения для деления на ноль (среди прочего), одним из которых является double.Infinity.

Если вас интересуют подробности, в спецификации с плавающей запятой (которая часто загадочна) есть страница в Википедии: http://en.wikipedia.org/wiki/IEEE_754-2008,, и ее полный текст также можно прочитать онлайн: http://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=4610933.

2 голосов
/ 13 марта 2011

1/0 - целочисленное деление, 1 / 0.0 - деление с плавающей запятой - числа с плавающей запятой могут представлять недопустимые значения, целые числа - нет.

1 голос
/ 13 марта 2011

IEEE определил определенные стандарты для чисел с плавающей запятой, которые включают определения «Не число», а также положительную и отрицательную бесконечность.Они не применяются к целым числам.

См. http://steve.hollasch.net/cgindex/coding/ieeefloat.html

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

0 голосов

fetestexcept и feenableexcept

Стоит отметить, что базовое аппаратное обеспечение ЦП может обнаружить конкретный случай 0.0 / 0.0 и:

  • установить некоторые биты флага, которые можно запросить с помощью ANSI C fetestexcept(FE_ALL_EXCEPT) == FE_INVALID
  • вызвать исключение, если это было включено с расширением feenableexcept(FE_INVALID) glibc

Однако я не смог найти, предоставляет ли Java эту функциональность.

Вот пример минимального запуска C: В чем разница между тихим NaN и сигнальным NaN?

...