2013-07-12 3 views
6

Когда я что-то вродеПочему Integer не представляет NaN в Java?

double a = 0.0; 
double b = 0.0; 
double c = a/b; 

Результат является Double.NaN писать, но когда я пытаюсь то же самое для целых чисел, он производит ArithmeticException. Итак, почему нет Integer.NaN?

+4

Поскольку спецификация с плавающей точкой указывает значение «NaN», и соответствующая реализация должна вести правильный путь обработки.Целочисленная реализация не существует, и нет никакого способа явно сказать «недопустимое значение» [связанное] (http://en.wikipedia.org/wiki/NaN#Integer_NaN), [related2] (http://stackoverflow.com/ Вопросы/3949457/can-an-integer-be-nan-in-c) –

+2

Возможный дубликат [Почему деление на ноль с номерами с плавающей запятой (или двойной точностью) не вызывает java.lang.ArithmeticException:/by zero в Java ] (http://stackoverflow.com/questions/12954193/why-does-division-by-zero-with-floating-point-or-double-precision-numbers-not) – Lion

+0

Заглянув в историю вопроса, я отметил ваш вопрос с Java как языком программирования. Если вы говорите о другом языке, пожалуйста, пометьте как таковой. – Lion

ответ

4

По той же причине, что нет целого числа NaN на любом другом языке.

Современные компьютеры используют двоичное представление двоичного дополнения 2 для целых чисел, и это представление не имеет значения NaN. (Все значения в области типа представления представляют определенные целые числа.)

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

Теоретически, кто-то может изобрести альтернативное представление для целых чисел, которое включает NaN (или INF, или какое-либо другое экзотическое значение). Однако арифметика с использованием такого представления не будет поддерживаться аппаратным обеспечением. Хотя можно было бы реализовать его в программном обеспечении, было бы слишком дорого стоить ... и нежелательно в других отношениях включить эту поддержку в язык Java.

1 - Это, конечно, относительный, но я бы предположил, что программная реализация NaNs будет (по крайней мере) на порядок медленнее, чем аппаратное обеспечение. Если вы действительно, действительно, нуждались в этом, тогда это было бы приемлемо. Но подавляющее большинство целочисленных арифметических кодов не нуждается в этом. В большинстве случаев бросать исключение для «делить на ноль» просто отлично, и на порядок замедлить во всех целочисленных арифметических операциях ... неприемлемо.


В отличие:

  • "неиспользованные" значения в пространстве представления уже существуют
  • NaN и INF значения являются частью стандарта IEE с плавающей точкой, и
  • они (обычно), реализованный на основе аппаратной реализации арифметики с плавающей запятой
+0

Я не согласен с «непомерно дорогостоящими» - это относительный термин, он может быть дешевле, чем стоимость кодирования по этой проблеме. И нежелательно - может быть, не знаю. Я бы сказал, что если понятие существует для двойного, это может быть удобно для ints. Это связано только с тем, что базовая реализация int не предусматривает, что это не делается, что практически подразумевает, что, поскольку внутреннее представление double и диапазон * позволяют *, это означает, что это хорошая идея, которая нуждается в другой реализации. – Bohemian

+1

@Bohemian - мы говорим о том, что это невероятно дорого, чтобы сделать число NaN частью «языка». Очевидно, что если для приложения действительно нужны NaN, для них это не слишком дорого. Но большинство нет. –

+0

Да, я знаю, что вы имели в виду. Но этот «расход» (помимо усилий по изменению языка, который не влияет на нас, программистов) в конечном итоге приведет к более высокому использованию ЦП при работе с ints, и это * это * стоимость (которая может быть конвертирована в доллары) что я сравниваю «стоимость» дополнительной функциональности (снова конвертируемой в доллары). Является ли это «запретительным» или нет, зависит от этих долларов. Я действительно сомневаюсь в том, будет ли это «запретительным» - мы говорим об изменении или, скорее, добавлении к основной реализации, которую следует оставить «скрытой», – Bohemian

0

Как отмечалось в других комментариях, это во многом потому, что NaN является стандартным значением чисел с плавающей запятой. Вы можете прочитать о причинах NaN будут возвращены в Википедии здесь:

http://en.wikipedia.org/wiki/NaN

Обратите внимание, что только одна из этих причин существует для целых чисел (деление на ноль). Существует также положительное и отрицательное значение бесконечности для чисел с плавающей запятой, которые целые числа не имеют и тесно связаны с NaN в спецификации с плавающей точкой.

8

Ответ имеет очень мало общего с Java. Бесконечность или неопределенные числа не являются частью целочисленного набора, поэтому они исключаются из Integer, тогда как типы с плавающей точкой представляют действительные числа, а также комплексные числа, поэтому для решения этих проблем NaN был включен в типы с плавающей точкой.

+0

Trivia (l?): Int i = (int) Float.NaN; // 0 – TWiStErRob

Смежные вопросы