Почему Math.pow(0, 0) === 1?
Мы все знаем, что 0 0 неопределен.
Но, javascript говорит, что:
Math.pow(0, 0) === 1 // true
и С++ говорит то же самое:
pow(0, 0) == 1 // true
Почему?
Я знаю, что:
>Math.pow(0.001, 0.001)
0.9931160484209338
Но почему Math.pow(0, 0)
не выдает ошибок? Или, может быть, NaN
будет лучше, чем 1
.
Ответы
Ответ 1
В С++ Результат pow (0, 0) результат в основном определяется реализацией, поскольку математически мы имеем противоречивую ситуацию, когда N^0
всегда должен быть 1
, но 0^N
всегда должен быть 0
для N > 0
, поэтому у вас не должно быть математически ожиданий относительно результата этого. Это сообщение Wolfram Alpha содержит более подробные сведения.
Несмотря на то, что pow(0,0)
результат 1
полезен для многих приложений, поскольку Обоснование для международных языков стандартного программирования-C указано в разделе, посвященном IEC 60559 арифметическая поддержка с плавающей запятой:
Как правило, C99 избегает результата NaN, где полезно числовое значение. [...] Результаты pow (∞, 0) и pow (0,0) равны 1, потому что есть приложения, которые могут использовать это определение. Например, если x (p) и y (p) - любые аналитические функции, которые становятся равными нулю при p = a, то pow (x, y), равная exp (y * log (x)), приближается к 1 по мере приближения p а.
Обновить С++
Как правильно указывали leemes, я первоначально был связан со ссылкой на сложную версию pow, в то время как некомплексная версия утверждает, что это ошибка домена черновик стандарта С++ возвращается к проекту стандарта C и как C99, так и C11 в разделе 7.12.7.4
В параграфах функций pow сказано: (внимание мое):
[...] Ошибка домена может иметь место, если x равно нулю, а y равно нулю. [...]
который, насколько я могу судить, означает, что это поведение неуказанное поведение Отключение части бит 7.12.1
Обработка условий ошибки говорит:
[...] ошибка домена возникает, если входной аргумент находится вне домена поверх который определен математической функцией. [...] При ошибке домена функция возвращает значение, определенное реализацией; если целочисленное выражение math_errhandling и MATH_ERRNO отличное от нуля, целочисленное выражение errno приобретает значение EDOM; [...]
Таким образом, если бы была ошибка домена, это было бы определением, определяемым реализацией, но в обеих последних версиях gcc
и clang
значение errno
равно 0
, поэтому это не ошибка домена для тех составители.
Обновить Javascript
Для Javascript Спецификация языка ECMAScript® в разделе 15.8
Математический объект в 15.8.2.13
pow (x, y) говорит среди других условий, что:
Если y равно +0, результат равен 1, даже если x является NaN.
Ответ 2
В JavaScript Math.pow
определяется следующим образом:
- Если y является NaN, результатом является NaN.
- Если y равно +0, результат равен 1, даже если x является NaN.
- Если y равно -0, результат равен 1, даже если x является NaN.
- Если x является NaN и y отличен от нуля, результатом является NaN.
- Если abs (x) > 1 и y равно + ∞, результат равен + ∞.
- Если abs (x) > 1 и y равно -∞, результат равен +0.
- Если abs (x) == 1 и y равно + ∞, результат равен NaN.
- Если abs (x) == 1 и y равно -∞, результат равен NaN.
- Если abs (x) < 1 и y равно + ∞, результат равен +0.
- Если abs (x) < 1 и y равно -∞, результат равен + ∞.
- Если x равно + ∞ и y > 0, результат равен + ∞.
- Если x равно + ∞ и y < 0, результат равен +0.
- Если x - -∞ и y > 0, а y - нечетное целое число, результат равен -∞.
- Если x - -∞ и y > 0, а y не является нечетным целым числом, то результат равен + ∞.
- Если x - -∞ и y < 0, а y - нечетное целое число, результат равен -0.
- Если x is -∞ и y < 0 и y не является нечетным целым числом, результат равен +0.
- Если x равно +0 и y > 0, результат равен +0.
- Если x равно +0 и y < 0, результат равен + ∞.
- Если x равно -0 и y > 0, а y - нечетное целое число, результат равен -0.
- Если x равно -0 и y > 0, а y не является нечетным целым числом, результат равен +0.
- Если x равно -0 и y < 0, а y - нечетное целое число, результат равен -∞.
- Если x равно -0 и y < 0, а y не является нечетным целым числом, то результат равен + ∞.
- Если x < 0 и x конечны и y конечен, а y не является целым числом, то результатом является NaN.
акцент мой
как правило, родные функции для любого языка должны работать, как описано в спецификации языка. Иногда это включает явно "поведение undefined", где оно должно быть реализовано разработчиком, чтобы определить, каким должен быть результат, однако это не относится к поведению undefined.
Ответ 3
Просто условно определить его как 1
, 0
или оставить его undefined
. Определение
широко распространено из-за следующего определения:
![mathematical power definition]()
Документация ECMA- Script гласит следующее о pow(x,y)
:
- Если y равно +0, результат равен 1, даже если x является NaN.
- Если y равно -0, результат равен 1, даже если x является NaN.
[http://www.ecma-international.org/ecma-262/5.1/#sec-15.8.2.13]
Ответ 4
Согласно Википедии:
В большинстве настроек, не связанных с непрерывностью в экспоненте, интерпретация 0 0 как 1 упрощает формулы и устраняет необходимость в особых случаях в теоремах.
Существует несколько возможных способов лечения 0**0
с плюсами и минусами каждого (см. Wikipedia для расширенного обсуждения).
Стандарт с плавающей запятой IEEE 754-2008 рекомендует три различные функции:
-
pow
рассматривает 0**0
как 1
. Это самая старая версия. Если мощность является точным целым, результат будет таким же, как и для pown
, иначе результат будет таким же, как и для powr
(за исключением некоторых исключительных случаев).
-
pown
обрабатывает 0 ** 0 как 1. Мощность должна быть точным целым числом. Значение определено для отрицательных оснований; например, pown(−3,5)
составляет −243
.
-
powr
обрабатывает 0 ** 0 как NaN (Not-a-Number - undefined). Значение также NaN для таких случаев, как powr(−3,2)
, где база меньше нуля. Значение определяется значением exp (power '× log (base)).
Ответ 5
Дональд Кнут
отчасти решила эту дискуссию в 1992 году со следующим:
![enter image description here]()
И еще более подробно описал в своей статье Две заметки о нотации.
В принципе, хотя мы не имеем 1 как предел f(x)/g(x)
для всех не всех функций f(x)
и g(x)
, он все же делает комбинаторику намного проще определять 0^0=1
, а затем просто делать специальные случаи в тех немногих местах, где вам нужно рассмотреть такие функции, как 0^x
, которые в любом случае являются странными. Ведь x^0
появляется намного чаще.
Некоторые из лучших обсуждений, которые я знаю об этой теме (кроме бумаги Кнута):
Ответ 6
Если вы хотите узнать, какое значение вы должны дать f(a)
, когда f
не может быть непосредственно вычислимым в a
, вы вычисляете предел f
, когда x
стремится к a
.
В случае x^y
обычные пределы стремятся к 1
, когда x
и y
стремятся к 0
, и особенно x^x
стремится к 1
, когда x
стремится к 0
.
См. http://www.math.hmc.edu/funfacts/ffiles/10005.3-5.shtml
Ответ 7
Определение языка C говорит (7.12.7.4/2):
Ошибка домена может возникнуть, если x равно нулю, а y равно нулю.
В нем также говорится (7.12.1/2):
При ошибке домена функция возвращает значение, определенное реализацией; если целочисленное выражение math_errhandling и MATH_ERRNO отличное от нуля, целочисленное выражение errno приобретает значение EDOM; если целочисленное выражение math_errhandling и MATH_ERREXCEPT отличное от нуля, возникает недопустимое исключение с плавающей запятой.
По умолчанию значение math_errhandling
равно MATH_ERRNO
, поэтому проверьте errno
на значение EDOM
.
Ответ 8
Я хотел бы не согласиться с утверждением предыдущих ответов о том, что это вопрос согласия или удобства (охватывающий некоторые частные случаи для различных теорем и т.д.), что 0 ^ 0 определяется как 1 вместо 0.
Экспоненциация на самом деле не соответствует этим другим математическим обозначениям, поэтому определение, которое мы все изучаем, оставляет место для путаницы. Немного другой способ приближения к нему - сказать, что a ^ b (или exp (a, b), если хотите) возвращает значение мультипликативно эквивалентное для умножения некоторой другой вещи через a, повторяется b раз.
Когда мы умножаем 5 на 4, 2 раза, получаем 80. Мы умножили 5 на 16. Итак, 4 ^ 2 = 16.
Когда вы умножаете 14 на 0, 0 раз, мы остаемся с 14. Мы умножили его 1. Следовательно, 0 ^ 0 = 1.
Эта линия мышления может также помочь прояснить отрицательные и дробные показатели. 4 ^ (- 2) является шестнадцатым, потому что "отрицательное умножение" является делением - мы делим на четыре раза.
a ^ (1/2) является корнем (a), потому что умножение чего-либо на корень a составляет половину мультипликативной работы, умножая ее на себя - вам придется сделать это дважды умножить что-то на 4 = 4 ^ 1 = (4 ^ (1/2)) ^ 2
Ответ 9
Чтобы это понять, вам нужно решить исчисление:
![введите описание изображения здесь]()
Развернув x^x
вокруг нуля с помощью серии Тейлора, получим:
![введите описание изображения здесь]()
Итак, чтобы понять, что происходит с пределом, когда x
обращается в нуль,
нам нужно выяснить, что происходит со вторым членом x log(x)
, поскольку другие члены пропорциональны x log(x)
, поднятым до некоторой степени.
Нам нужно использовать преобразование:
![введите описание изображения здесь]()
Теперь после этого преобразования мы можем использовать правило L'Hôpital, в котором говорится, что:
![введите описание изображения здесь]()
Итак, дифференцируем это преобразование:
![введите описание изображения здесь]()
Итак, мы вычислили, что термин log(x)*x
приближается к 0, когда x приближается к 0.
Легко видеть, что другие последовательные члены также приближаются к нулю и даже быстрее второго члена.
Итак, в точке x=0
серия становится 1 + 0 + 0 + 0 + ...
и, следовательно, равна 1.