simbolo - raiz cuadrada javascript
¿Por qué Math.pow(0, 0)=== 1? (9)
Todos sabemos que 0 0 es indeterminado.
Pero , javascript dice que:
Math.pow(0, 0) === 1 // true
y C ++ dice lo mismo:
pow(0, 0) == 1 // true
¿POR QUÉ?
Yo sé eso:
>Math.pow(0.001, 0.001)
0.9931160484209338
¿Pero por qué Math.pow(0, 0)
no arroja errores? O tal vez un NaN
sería mejor que 1
.
Donald Knuth
tipo de resolver este debate en 1992 con lo siguiente:
Y profundizó aún más en los detalles en su documento Two Notes on Notation .
Básicamente, si bien no tenemos 1 como el límite de f(x)/g(x)
para todas las funciones f(x)
y g(x)
, todavía hace que la combinatoria sea mucho más simple para definir 0^0=1
, y luego solo haga casos especiales en los pocos lugares donde necesita considerar funciones como 0^x
, que de todos modos son raras. Después de todo, x^0
aparece mucho más a menudo.
Algunas de las mejores discusiones que conozco sobre este tema (aparte del artículo de Knuth) son:
Cuando desee saber qué valor le debe dar a f(a)
cuando f
no es directamente computable en a
, calcule el límite de f
cuando x
tiende hacia a
.
En el caso de x^y
, los límites habituales tienden hacia 1
cuando y
tienden a 0
, y especialmente x^x
tiende a 1
cuando x
tiende a 0
.
De acuerdo con Wikipedia:
En la mayoría de las configuraciones que no implican continuidad en el exponente, interpretar 0 0 como 1 simplifica las fórmulas y elimina la necesidad de casos especiales en los teoremas.
Hay varias maneras posibles de tratar 0**0
con pros y contras para cada uno (ver Wikipedia para una discusión extensa).
El estándar de coma flotante IEEE 754-2008 recomienda tres funciones diferentes:
-
pow
trata a0**0
como1
. Esta es la versión más antigua definida. Si la potencia es un número entero exacto, el resultado es el mismo que parapown
, de lo contrario el resultado es como parapowr
(excepto en algunos casos excepcionales). -
pown
trata 0 ** 0 como 1. La potencia debe ser un número entero exacto. El valor se define para bases negativas; por ejemplo,pown(−3,5)
es−243
. -
powr
trata 0 ** 0 como NaN (Not-a-Number - undefined). El valor también es NaN para casos comopowr(−3,2)
donde la base es menor que cero. El valor está definido por exp (power ''× log (base)).
En C ++ El resultado de pow (0, 0) el resultado es básicamente comportamiento definido de implementación ya que matemáticamente tenemos una situación contradictoria donde N^0
siempre debe ser 1
pero 0^N
siempre debe ser 0
para N > 0
, por lo que debe tener tampoco hay expectativas matemáticamente sobre el resultado de esto. Estas publicaciones en el foro de Wolfram Alpha entran en detalles un poco más.
Si bien tener pow(0,0)
resulta en 1
es útil para muchas aplicaciones, como lo es el Justificación para Lenguajes de Programación Estándar Internacional-C en la sección que cubre el soporte aritmético de punto flotante IEC 60559 :
Generalmente, C99 evita un resultado NaN donde un valor numérico es útil. [...] Los resultados de pow (∞, 0) y pow (0,0) son ambos 1, porque hay aplicaciones que pueden explotar esta definición. Por ejemplo, si x (p) ey (p) son funciones analíticas que se vuelven cero en p = a, entonces pow (x, y), que es igual a exp (y * log (x)), se acerca a 1 cuando p se acerca a.
Actualizar C ++
Como leemes señaló correctamente que originalmente me vinculé a la referencia para la versión compleja de pow, mientras que la versión non-complex afirma que es un error de dominio, el borrador del estándar de C ++ vuelve al borrador C estándar y tanto C99 como C11 en la sección 7.12.7.4
funciones de pow el párrafo 2 dice ( énfasis mío ):
[...] Un error de dominio puede ocurrir si x es cero e y es cero. [...]
que en lo que puedo decir significa que este comportamiento es un comportamiento no especificado Devolver un poco la sección 7.12.1
tratamiento de las condiciones de error dice:
[...] se produce un error de dominio si un argumento de entrada está fuera del dominio sobre el que se define la función matemática. [...] En un error de dominio, la función devuelve un valor definido por la implementación; si la expresión entera math_errhandling & MATH_ERRNO es distinta de cero, la expresión entera errno adquiere el valor EDOM; [...]
Entonces, si hubiera un error de dominio , este sería un comportamiento definido por la implementación, pero tanto en las últimas versiones de gcc
como en clang
el valor de errno
es 0
por lo que no es un error de dominio para esos compiladores.
Actualizar Javascript
Para Javascript, la especificación de idioma ECMAScript® en la sección 15.8
El objeto matemático en 15.8.2.13
pow (x, y) dice, entre otras condiciones, que:
Si y es +0, el resultado es 1, incluso si x es NaN.
Es simplemente una convención definirlo como 1
, 0
o dejarlo undefined
. La definición es muy extendido debido a la siguiente definición:
La documentación de ECMA-Script dice lo siguiente sobre pow(x,y)
:
- Si y es +0, el resultado es 1, incluso si x es NaN.
- Si y es -0, el resultado es 1, incluso si x es NaN.
[ http://www.ecma-international.org/ecma-262/5.1/#sec-15.8.2.13 ]
La definición del lenguaje C dice (7.12.7.4/2):
Un error de dominio puede ocurrir si x es cero e y es cero.
También dice (7.12.1 / 2):
En un error de dominio, la función devuelve un valor definido por la implementación; si la expresión entera math_errhandling & MATH_ERRNO es distinta de cero, la expresión entera errno adquiere el valor EDOM; si la expresión entera math_errhandling & MATH_ERREXCEPT es distinta de cero, se genera la excepción de punto flotante '''' no válida ''''.
De forma predeterminada, el valor de math_errhandling
es MATH_ERRNO
, por lo que verifique errno
para el valor EDOM
.
Me gustaría no estar de acuerdo con algunas de las afirmaciones de las respuestas anteriores de que es una cuestión de convención o conveniencia (que cubre algunos casos especiales para varios teoremas, etc.) que 0 ^ 0 se defina como 1 en lugar de 0.
La exponenciación en realidad no encaja tan bien con nuestras otras notaciones matemáticas, por lo que la definición que todos aprendemos deja espacio para la confusión. Una forma ligeramente diferente de abordarlo es decir que a ^ b (o exp (a, b), si lo desea) devuelve el valor multiplicativamente equivalente a multiplicar alguna otra cosa por a, repetida b veces.
Cuando multiplicamos 5 por 4, 2 veces, obtenemos 80. Hemos multiplicado 5 por 16. Entonces 4 ^ 2 = 16.
Cuando multiplicas 14 por 0, 0 veces, nos quedamos con 14. Lo hemos multiplicado 1. Por lo tanto, 0 ^ 0 = 1.
Esta línea de pensamiento también podría ayudar a aclarar los exponentes negativos y fraccionarios. 4 ^ (- 2) es un 16 °, porque ''multiplicación negativa'' es división - dividimos por cuatro dos veces.
a ^ (1/2) es raíz (a), porque multiplicar algo por la raíz de a es la mitad del trabajo multiplicativo que multiplicarlo por uno mismo - tendrías que hacerlo dos veces para multiplicar algo por 4 = 4 ^ 1 = (4 ^ (1/2)) ^ 2
Para que esto lo entienda, debe resolver el cálculo:
Expandiendo x^x
alrededor de cero usando la serie de Taylor, obtenemos:
Entonces, para entender qué está pasando con el límite cuando x
llega a cero, necesitamos averiguar qué está sucediendo con el segundo término x log(x)
, porque otros términos son proporcionales a x log(x)
elevado a alguna potencia.
Necesitamos usar la transformación:
Ahora, después de esta transformación, podemos usar la regla de L''Hôpital , que establece que:
Para diferenciar esa transformación obtenemos:
Así que calculamos que el término log(x)*x
acerca a 0 cuando x se aproxima a 0. Es fácil ver que otros términos consecutivos también se acercan a cero e incluso más rápido que el segundo término.
Entonces en el punto x=0
, la serie se convierte en 1 + 0 + 0 + 0 + ...
y por lo tanto es igual a 1.
En JavaScript Math.pow
se define de la siguiente manera :
- Si y es NaN, el resultado es NaN.
- Si y es +0, el resultado es 1, incluso si x es NaN.
- Si y es -0, el resultado es 1, incluso si x es NaN.
- Si x es NaN e y es distinto de cero, el resultado es NaN.
- Si abs (x)> 1 e y es + ∞, el resultado es + ∞.
- Si abs (x)> 1 e y es -∞, el resultado es +0.
- Si abs (x) == 1 e y es + ∞, el resultado es NaN.
- Si abs (x) == 1 e y es -∞, el resultado es NaN.
- Si abs (x) <1 e y es + ∞, el resultado es +0.
- Si abs (x) <1 e y es -∞, el resultado es + ∞.
- Si x es + ∞ y y> 0, el resultado es + ∞.
- Si x es + ∞ y y <0, el resultado es +0.
- Si x es -∞ y y> 0 e y es un entero impar, el resultado es -∞.
- Si x es -∞ y y> 0 e y no es un entero impar, el resultado es + ∞.
- Si x es -∞ y y <0 e y es un entero impar, el resultado es -0.
- Si x es -∞ y y <0 e y no es un entero impar, el resultado es +0.
- Si x es +0 ey> 0, el resultado es +0.
- Si x es +0 e y <0, el resultado es + ∞.
- Si x es -0 e y> 0 e y es un entero impar, el resultado es -0.
- Si x es -0 e y> 0 e y no es un entero impar, el resultado es +0.
- Si x es -0 e y <0 e y es un entero impar, el resultado es -∞.
- Si x es -0 y y <0, y y no es un entero impar, el resultado es + ∞.
- Si x <0 y x es finito e y es finito e y no es un entero, el resultado es NaN.
énfasis mío
como regla general, las funciones nativas de cualquier idioma deben funcionar como se describe en la especificación del lenguaje. A veces esto incluye explícitamente un "comportamiento indefinido" en el que depende del implementador determinar cuál debe ser el resultado, sin embargo, este no es un caso de comportamiento indefinido.