Почему число делится на ноль бесконечности в Java?
Почему следующий код в Java
System.out.println(new Integer(1)/ new Double(0));
выведите "Infinity" и не определите. Разве это не математически неправильно?
5 ответов
В математике есть много различных структур, которые поддерживают арифметику. Наиболее выдающиеся из них, такие как натуральные числа, целые и действительные числа, не включают бесконечность. В этих системах деление на ноль не поддерживается.
Другие системы включают в себя по крайней мере одну бесконечность. Смотрите, например, настоящую проективную линию. Это позволяет деление на ноль.
Есть только один способ узнать, что математически определено или не определено в конкретной системе - изучить эту систему.
Точно так же, являются ли операции коммутативными (a op b == b op a) и / или ассоциативными (a op (b op c) == (a op b) op c), зависит от системы и операции.
Бинарная система с плавающей точкой IEEE 754 - это система с конечным набором элементов, включающим две бесконечности. Сложение и умножение оба являются коммутативными, но не ассоциативными. Реальная Java и двойная арифметика основаны на этом. Спецификация языка Java - это единственный способ точно узнать, что определено или не определено в арифметике с плавающей запятой Java.
Многие из наихудших ошибок при использовании чисел с плавающей запятой основаны на предположении, что числа с плавающей запятой являются действительными числами, а не действительной, но другой системой.
Это согласуется со стандартом IEEE 754 по плавающей запятой, которому следует Java.
Нет, вы не можете делить на ноль в математике, но в Java Infinity
правильно для new Integer(1)/ new Double(0)
, new Integer(0)/ new Double(0)
будет неопределенным (NaN
).
Java следует стандартам IEEE, поэтому для операций с плавающей запятой, таких как эта, Infinity
верно. Если бы это было 1/0
, ArithmeticException
произошло бы, потому что при целочисленном делении деление на ноль не допускается; здесь нет int
представление для бесконечности.
В частности, в JLS, раздел 15.17.2:
[I] Если значение делителя в целочисленном делении равно 0, то генерируется исключение ArithmeticException.
А также
Результат деления с плавающей запятой определяется правилами арифметики IEEE 754:
Деление нуля на ноль приводит к NaN Деление ненулевого конечного значения на ноль приводит к бесконечности со знаком.
Вкратце: числа с плавающей запятой могут представлять бесконечность (или даже операции, которые дают значения, которые не являются числами), поэтому операция, которая приводит к этому (например, деление на 0), является допустимой.
Одним из лучших дизайнерских решений при разработке сегодняшних стандартов с плавающей точкой было то, что такие вещи, как деление на ноль, давали специальное дозорное значение, которое указывает, что что-то вышло за пределы диапазона, а не сбой программы. Код, который использует результат, может затем решить, в какой степени такое значение дозорного указывает на серьезную проблему или второстепенную. Например, программа, которая отображает график функции, может просто пропустить точки, где значение не может быть вычислено при построении графика остальных.
Редко выводится число с плавающей запятой в качестве его истинного значения. Вместо этого он выведет некоторую строку, достаточную для определения ее значения. Значение часового, которое генерируется при делении ненулевого числа на ноль, печатается как "Бесконечность", но это не означает, что это математически бесконечность. Скорее, это означает, что именно это дозорное значение используется для представления результата, который неотличим от любого другого числа, превышающего примерно 2^1024, и должно ранжироваться больше, чем любой другой определенный результат. Для результата существует другое значение дозорного, которое неотличимо от любого другого числа, меньшего -(2^1024), и должно иметь рейтинг меньше, чем любой другой определенный результат. Третий существует для результатов, которые не могут быть вычислены, но не соответствуют ни одной категории.
Причина использования одного и того же стража для вычислений, которые превышают 2^1024 и деления положительного числа на ноль, состоит в том, что обе ситуации могут возникнуть при делении очень большого положительного числа на очень маленькое. Если результатом такого сравнения будет "положительная бесконечность", сортирующая выше всего остального, даже при делении на бесконечно малое положительное число, оно должно остаться при делении на "половину" этого числа (которое округляется до нуля).