Почему NaN ^ 0 == 1

Подсказка с точки зрения более раннего кодирования кода, почему бы:

>NaN^0
[1] 1

Для NA^0 имеет смысл быть 1, потому что NA отсутствует данные, а любое число, поднятое до 0, даст 1, включая -Inf и Inf. Однако NaN должен представлять не-число, так почему это так? Это еще более запутывает/беспокоит, когда на странице справки ?NaN указано:

В R, в основном, все математические функции (включая базовые Арифметика), должны нормально работать с +/- Inf и NaN как ввода или вывода.

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

Вычисления с участием NaN вернут NaN или, возможно, NA: какой из эти два не гарантируются и могут зависеть от платформы R (поскольку компиляторы могут переупорядочивать вычисления).

Есть ли философская причина этого, или это просто связано с тем, как R представляет эти константы?

Ответ 1

Это ссылается на странице справки, на которую ссылается ?'NaN'

"Стандарт IEC 60559, также известный как стандарт плавающей точки ANSI/IEEE 754.

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

И вы найдете это утверждение относительно того, что должно создать NaN:

 "There are three kinds of operations that can return NaN:[5]
       Operations with a NaN as at least one operand.

Вероятно, это от конкретного компилятора C, как это указано в заметке, на которую вы ссылались. Это то, что говорит документация GNU C:

http://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html

"NaN, с другой стороны, заражает любые вычисления, которые его включают. Если расчет не даст тот же результат независимо от того, какое реальное значение заменило NaN, результатом будет NaN."

Таким образом, кажется, что люди GNU-C имеют разные стандарты при написании своего кода. И сообщается, что версия версии ANSI/IEEE 754 с плавающей запятой 2008 года делает это предложение:

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

Опубликованный стандарт не является бесплатным. Поэтому, если у вас есть права доступа или деньги, вы можете посмотреть здесь:

http://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=4610933

Ответ 2

Ответ можно суммировать по "по историческим причинам".

Кажется, что IEEE 754 ввел два различных функций питания - pow и powr, причем последний сохранил NaN в случае OP, а также возвратил NaN для Inf^0, 0^0, 1^Inf, но, в конце концов, последний был отброшен как здесь кратко..

Концептуально, я в лагере сохранения NaN, потому что я прихожу к проблеме с точки зрения ограничений, но с удобной точки зрения я ожидаю, что существующие соглашения будут немного легче справиться, даже если они В некоторых случаях это имеет большой смысл (например, sqrt(-1)^0, равный 1, а все операции на действительных числах мало смысла, если они есть).

Ответ 3

Да, я опаздываю здесь, но как член R Core, который участвовал в этом проекте, позвольте мне вспомнить, что я прокомментировал выше. Сохранение NaN и сохранение N сохраняют работу "эквивалентно" в R, поэтому, если вы согласитесь, что NA ^ 0 должно давать 1, NaN ^ 0 | → 1 является следствием.

В действительности (как говорили другие) вы должны действительно читать страницы помощи R, а не C или IEEE, чтобы ответить на такие вопросы, и SimonO101 правильно цитируется

1 ^ y и y ^ 0 равны 1, всегда

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

Или иначе, простое правило, как указано выше (возвращение не NaN во всех случаях) является хорошим правилом, поскольку оно распространяет непрерывность в математическом смысле: lim_x f (x) = f (lim x). У нас было несколько случаев, когда это было явно выгодно (т.е. Не нуждалось в специальной оболочке, повторяю.), Чтобы придерживаться вышеизложенного правила "= 1", а не распространять NaN. Как я сказал далее, sqrt (-1) ^ 0 также является таким примером, поскольку 1 является правильным результатом, как только вы переходите к сложной плоскости.

Ответ 4

Вот одна из причин. Из Goldberg:

В IEEE 754 NaN часто представлены в виде чисел с плавающей запятой с показатель e_max + 1 и ненулевые значения.

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

Также обратите внимание:

> 1^NaN
[1] 1

Один - это число, показатель которого уже равен нулю.

Ответ 5

Концептуально единственная проблема с NaN^0 == 1 заключается в том, что нулевые значения могут возникать как минимум четыре разных способа, но формат IEEE использует то же представление для трех из них. Вышеупомянутый смысл равенства формулы для наиболее распространенного случая (который является одним из трех), но не для других.

Кстати, четыре случая, которые я бы узнал, были бы следующими:

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

Некоторые из них могут быть получены с помощью других средств (например, буквальный нуль может быть получен как сумма двух буквальных нулей, положительная бесконечно малая из-за деления очень небольшого числа на очень большое и т.д.).

Если точка с плавающей точкой распознала вышеизложенное, полезно было бы рассмотреть вопрос о повышении NaN до литерального нуля, как уступающего, и подведении его к любому другому виду нуля с получением NaN; такое правило позволило бы во многих случаях предполагать постоянный результат, когда что-то, что может быть NaN, было бы поднято до того, что компилятор мог идентифицировать как постоянный нуль, без такого предположения, изменяющего семантику программы. В противном случае, я думаю, проблема в том, что большинство кода не заботятся о том, может ли x^0 быть NaN, если x есть NaN, и не так много смысла, чтобы компилятор добавлял код для условия кода isn ' t заботиться о. Обратите внимание, что проблема - это не просто код для вычисления x^0, а для любых вычислений, основанных на том, что было бы постоянным, если бы x^0 был.

Ответ 6

Если вы посмотрите на тип NaN, это все равно номер, это просто не конкретное число, которое может быть представлено числовым типом.

EDIT:

Например, если вы должны были взять 0/0. Что в итоге? Если вы попытаетесь решить это уравнение на бумаге, вы застряли на самой первой цифре, сколько нулей поместилось в другую 0? Вы можете положить 0, вы можете положить 1, вы можете положить 8, все они вписываются в 0 * x = 0, но невозможно узнать, какой из них правильный. Однако это не означает, что ответ больше не является числом, это просто не число, которое может быть представлено.

Независимо от того, что любое число, даже число, которое вы не можете представить, равным нулю, равно 1. Если вы отделите некоторую математику x^8 * x^0, можно еще упростить с помощью x^(8+0), которая приравнивается к x^8, где проходил x^0? Имеет смысл, если x^0 = 1, потому что тогда уравнение x^8 * 1 объясняет, почему x^0 просто исчезает из существования.