Todos nós sabemos que 0 0 é indeterminado.
Mas , javascript diz que:
Math.pow(0, 0) === 1 // true
e C ++ diz a mesma coisa:
pow(0, 0) == 1 // true
PORQUE?
Eu sei disso:
>Math.pow(0.001, 0.001)
0.9931160484209338
Mas por que não Math.pow(0, 0)
lança nenhum erro? Ou talvez NaN
seja melhor do que 1
.
javascript
c++
language-agnostic
pow
Ionică Bizău
fonte
fonte
Respostas:
Em C ++
O resultado de pow (0, 0), o resultado é basicamente implementação comportamento definido desde matematicamente temos uma situação contraditória em queN^0
deve ser sempre1
, mas0^N
deve ser sempre0
paraN > 0
, então você não deve ter expectativas matematicamente quanto ao resultado deste quer. Esta postagem do fórum do Wolfram Alpha dá mais detalhes.Embora ter
pow(0,0)
resultado em1
seja útil para muitas aplicações, como a justificativa para o padrão internacional - linguagens de programação - C afirma na seção que cobre o suporte aritmético de ponto flutuante IEC 60559 :Atualizar C ++
Como leemes corretamente apontou, eu originalmente vinculei à referência para a versão complexa de pow enquanto a versão não complexa afirma que é um erro de domínio, o esboço do padrão C ++ volta ao esboço do padrão C e ambos C99 e C11 na seção
7.12.7.4
O parágrafo das funções pow 2 diz ( ênfase minha ):que, tanto quanto eu posso dizer meio deste comportamento é o comportamento não especificado liquidação de volta uma seção pouco
7.12.1
Tratamento de condições de erro diz:Portanto, se houvesse um erro de domínio , esse seria o comportamento definido pela implementação, mas em ambas as versões mais recentes de
gcc
eclang
o valor deerrno
é,0
portanto, não é um erro de domínio para esses compiladores.Atualizar Javascript
Para Javascript, a Especificação da Linguagem ECMAScript® na seção
15.8
O Objeto Matemático sob15.8.2.13
pow (x, y) diz, entre outras condições:fonte
Em JavaScript
Math.pow
é definido da seguinte forma :ênfase minha
como regra geral, as funções nativas de qualquer idioma devem funcionar conforme descrito na especificação do idioma. Às vezes, isso inclui explicitamente "comportamento indefinido", em que cabe ao implementador determinar qual deve ser o resultado; no entanto, esse não é um caso de comportamento indefinido.
fonte
__STDC_IEC_559__
para anunciar que está em conformidade com esta especificação. O anexo F descreve a aritmética de ponto flutuante IEC 60559. Eu acredito que uma especificação C pode estar parcialmente em conformidade com o Anexo F (por exemplo, pow (0, 0) == 1) e não definir__STDC_IEC_559__
.É apenas uma convenção para defini-lo como
1
,0
ou para deixá-loundefined
. A definição é ampla devido à seguinte definição:A documentação do ECMA-Script diz o seguinte sobre
pow(x,y)
:[ http://www.ecma-international.org/ecma-262/5.1/#sec-15.8.2.13 ]
fonte
De acordo com a Wikipedia:
Existem várias maneiras possíveis de tratar os
0**0
prós e os contras de cada um (consulte a Wikipedia para uma discussão extensa).O padrão de ponto flutuante IEEE 754-2008 recomenda três funções diferentes:
pow
trata0**0
como1
. Esta é a versão mais antiga definida. Se a potência for um inteiro exato, o resultado é o mesmo que parapown
, caso contrário, o resultado é igual apowr
(exceto em alguns casos excepcionais).pown
trata 0 ** 0 como 1. A potência deve ser um número inteiro exato. O valor é definido para bases negativas; por exemplo,pown(−3,5)
é−243
.powr
trata 0 ** 0 como NaN (não é um número - indefinido). O valor também é NaN para casos empowr(−3,2)
que a base é menor que zero. O valor é definido por exp (potência '× log (base)).fonte
Donald Knuth
meio que resolveu esse debate em 1992 com o seguinte:
E entrou ainda mais em detalhes em seu artigo Two Notes on Notation .
Basicamente, embora não tenhamos 1 como o limite de
f(x)/g(x)
para todas nem todas as funçõesf(x)
eg(x)
, ainda torna a combinatória muito mais simples de definir0^0=1
e, em seguida, apenas cria casos especiais nos poucos lugares onde você precisa considerar funções como0^x
, que são estranhos de qualquer maneira. Afinal,x^0
surge com muito mais frequência.Algumas das melhores discussões que conheço sobre este tópico (além do artigo de Knuth) são:
fonte
Quando você quer saber a qual valor deve dar
f(a)
quandof
não é diretamente computável ema
, você calcula o limite def
quandox
tende paraa
.No caso de
x^y
, os limites usuais tendem para1
quandox
ey
tendem para0
, e especialmentex^x
tendem para1
quandox
tendem para0
.Consulte http://www.math.hmc.edu/funfacts/ffiles/10005.3-5.shtml
fonte
A definição da linguagem C diz (7.12.7.4/2):
Também diz (7.12.1 / 2):
Por padrão, o valor de
math_errhandling
éMATH_ERRNO
, portanto, verifiqueerrno
o valorEDOM
.fonte
g++ (Ubuntu/Linaro 4.8.1-10ubuntu8) 4.8.
Eu gostaria de discordar da afirmação de algumas das respostas anteriores de que é uma questão de convenção ou conveniência (cobrindo alguns casos especiais para vários teoremas, etc.) que 0 ^ 0 seja definido como 1 em vez de 0.
A exponenciação não se encaixa muito bem com nossas outras notações matemáticas, então a definição que todos aprendemos deixa espaço para confusão. Uma maneira ligeiramente diferente de abordar isso é dizer que a ^ b (ou exp (a, b), se quiser) retorna o valor multiplicativamente equivalente a multiplicar alguma outra coisa por a, repetido b vezes.
Quando multiplicamos 5 por 4, 2 vezes, obtemos 80. Multiplicamos 5 por 16. Portanto, 4 ^ 2 = 16.
Quando você multiplica 14 por 0, 0 vezes, ficamos com 14. Nós multiplicamos 1. Portanto, 0 ^ 0 = 1.
Essa linha de pensamento também pode ajudar a esclarecer os expoentes negativos e fracionários. 4 ^ (- 2) é um 16º, porque 'multiplicação negativa' é divisão - dividimos por quatro duas vezes.
a ^ (1/2) é root (a), porque multiplicar algo pela raiz de a é metade do trabalho multiplicativo como multiplicar por a ele mesmo - você teria que fazer isso duas vezes para multiplicar algo por 4 = 4 ^ 1 = (4 ^ (1/2)) ^ 2
fonte
Para que isso entenda, você precisa resolver o cálculo:
Expandindo em
x^x
torno de zero usando a série Taylor, obtemos:Então, para entender o que está acontecendo com o limite quando
x
vai para zero, precisamos descobrir o que está acontecendo com o segundo mandatox log(x)
, porque outros termos são proporcionais ax log(x)
elevados a alguma potência.Precisamos usar a transformação:
Agora, após esta transformação, podemos usar a regra de L'Hôpital , que afirma que:
Assim, diferenciando essa transformação, obtemos:
Portanto, calculamos que o termo se
log(x)*x
aproxima de 0 quando x se aproxima de 0. É fácil ver que outros termos consecutivos também se aproximam de zero e ainda mais rápido do que o segundo termo.Então, nesse ponto
x=0
, a série se torna1 + 0 + 0 + 0 + ...
e, portanto, é igual a 1.fonte