двойной d = 1/0,0 против двойной d = 1/0

double d=1/0.0;
    System.out.println(d);

Он печатает Infinity , но если мы напишем double d=1/0; и напечатаем его, мы получим это исключение: Exception in thread "main" java.lang.ArithmeticException: / by zero at D.main(D.java:3) Почему Java знает в одном случае, что погружение на ноль — это бесконечность, но для int 0 это не определено? В обоих случаях d двойное, и в обоих случаях результат равен бесконечности.


person Numerator    schedule 10.09.2011    source источник


Ответы (2)


Типы данных с плавающей запятой имеют специальное значение, зарезервированное для представления бесконечности, а целочисленные значения — нет.

В вашем коде 1/0 — это целочисленное деление, которое, конечно же, терпит неудачу. Однако 1/0.0 является делением с плавающей запятой, поэтому в результате получается Infinity.

person David Heffernan    schedule 10.09.2011
comment
Как только вы сделаете неявные приведения явными, double d=1/0 будет таким же, как double d=(double) (1/0), тогда как double d=1/0.0 будет таким же, как double d=((double) 1)/0.0d. - person Mike Samuel; 10.09.2011

строго говоря, 1.0/0.0 вовсе не бесконечность, она не определена.

Как говорит Дэвид в своем ответе, у поплавков есть способ выразить число, которое не находится в диапазоне от самого высокого числа, которое оно может представлять, до самого низкого. Эти значения известны под общим названием «Не число» или просто NaN. NaN также может возникать из-за вычислений, которые действительно бесконечны (например, limx -> 0 ln2 x), значений, которые являются конечными, но выходят за пределы диапазона с плавающей запятой (например, 10100100), а также как неопределенные значения, такие как 1/0.

Числа с плавающей запятой не совсем четко различают неопределенные значения, переполнение и бесконечность; какая комбинация битов получается в результате этого вычисления, зависит. Поскольку просто напечатать «NaN» или «Не число» немного сложнее понять людям, которые не знают, как представлены значения с плавающей запятой, этот форматировщик просто печатает «Бесконечность» или иногда «-Бесконечность». Поскольку он обеспечивает то же самое уровень информации, когда вы знаете, что такое FP NaN, и имеет какое-то значение, когда вы этого не знаете.

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

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

person SingleNegationElimination    schedule 10.09.2011
comment
В Java 1.0/0.0 определяется как бесконечность. Я не согласен с тем, что единицы с плавающей запятой не различают Infinity и NaN. Sqrt(-1.0) — это NaN, но переполнение приводит к Infinity. Вы утверждаете, что средство форматирования выводит Infinity для NaN? - person David Heffernan; 10.09.2011
comment
Хм.. Признаюсь, я не очень хорошо знаю java. Если то, что вы говорите, верно, что 1.0/0.0 — это бесконечность, то я должен сказать, что java неправильно. - person SingleNegationElimination; 10.09.2011
comment
У меня такое ощущение, что 1.0/0.0=Infinity является частью IEEE754, но почему вы говорите, что это неправильно? - person David Heffernan; 10.09.2011