Ответ 1
Это потому, что целые числа не имеют значений для +/- Inf, NaN и не допускают деления на 0, в то время как поплавки имеют эти специальные значения.
Мне просто интересно:
При оценке 1/0
в Java возникает следующее исключение:
Исключение в потоке "main" 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);
}
}
Почему это происходит?
Это потому, что целые числа не имеют значений для +/- Inf, NaN и не допускают деления на 0, в то время как поплавки имеют эти специальные значения.
1/0 - это деление двух ints и генерирует исключение, потому что вы не можете делить на целое число. Однако 0.0 является литералом типа double, а Java будет использовать деление с плавающей запятой. Спецификация с плавающей точкой IEEE имеет специальные значения для деления на ноль (между прочим), одна из которых - double.Infinity.
Если вам интересны детали, спецификация с плавающей запятой (которая часто является загадочной) содержит страницу в Википедии: http://en.wikipedia.org/wiki/IEEE_754-2008, а его полный текст можно также прочитать онлайн: http://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=4610933.
1/0 - целочисленное деление, 1/0.0 - деление с плавающей запятой. Поплавки могут представлять недопустимые значения, целые числа не могут.
IEEE определил определенные стандарты для чисел с плавающей запятой, которые включают определения "Не число" и положительную и отрицательную бесконечность. Они не применяются к целым числам.
См. http://steve.hollasch.net/cgindex/coding/ieeefloat.html
Причина этих особых случаев в случае ошибок округления. Числа с плавающей запятой часто всегда усекаются, потому что они никогда не точны. С другой стороны, целые числа всегда точны.
fetestexcept
и feenableexcept
Стоит отметить, что базовое аппаратное обеспечение ЦП может обнаружить конкретный случай 0.0/0.0
, и:
fetestexcept(FE_ALL_EXCEPT) == FE_INVALID
ANSI C fetestexcept(FE_ALL_EXCEPT) == FE_INVALID
feenableexcept(FE_INVALID)
Я не мог найти, предоставляет ли Java эту функциональность как бы то ни было.
Вот минимальный работающий пример C: в чем разница между тихим NaN и сигнальным NaN?