Nous savons tous que 0 0 est indéterminé.
Mais , javascript dit que:
Math.pow(0, 0) === 1 // true
et C ++ dit la même chose:
pow(0, 0) == 1 // true
POURQUOI?
Je le sais:
>Math.pow(0.001, 0.001)
0.9931160484209338
Mais pourquoi ne Math.pow(0, 0)
jette aucune erreur? Ou peut-être que ce NaN
serait mieux que 1
.
javascript
c++
language-agnostic
pow
Ionică Bizău
la source
la source
Réponses:
En C ++
Le résultat de pow (0, 0)le résultat est fondamentalement un comportement défini par l'implémentation puisque mathématiquement nous avons une situation contradictoire oùN^0
devrait toujours être1
mais0^N
devrait toujours être0
pourN > 0
, donc vous ne devriez pas non plus avoir d'attentes mathématiques quant au résultat de ceci. Ce message du forum Wolfram Alpha donne un peu plus de détails.Bien que le
pow(0,0)
résultat en1
soit utile pour de nombreuses applications, comme l' indique la justification de la Norme internationale - Langages de programmation - C dans la section traitant de la prise en charge arithmétique à virgule flottante CEI 60559 :Mettre à jour C ++
Comme leemes l'a correctement souligné, j'ai initialement lié à la référence pour la version complexe de pow tandis que la version non complexe prétend qu'il s'agit d'une erreur de domaine, le projet de norme C ++ revient au projet de norme C et à la fois C99 et C11 dans la section
7.12.7.4
Le paragraphe des fonctions pow 2 dit (c'est moi qui souligne ):ce qui, pour autant que je sache, signifie que ce comportement est un comportement non spécifié Remonter un peu la section
7.12.1
Traitement des conditions d'erreur dit:Donc, s'il y avait une erreur de domaine, il s'agirait d'un comportement défini par l'implémentation, mais dans les deux dernières versions de
gcc
etclang
la valeur deerrno
est0
donc ce n'est pas une erreur de domaine pour ces compilateurs.Mettre à jour Javascript
Pour Javascript, la spécification du langage ECMAScript® dans la section
15.8
L'objet mathématique sous15.8.2.13
pow (x, y) dit entre autres conditions que:la source
En JavaScript
Math.pow
est défini comme suit :accent le mien
en règle générale, les fonctions natives de n'importe quelle langue doivent fonctionner comme décrit dans la spécification du langage. Parfois, cela inclut explicitement un «comportement indéfini» où c'est à l'implémenteur de déterminer ce que le résultat devrait être, cependant ce n'est pas un cas de comportement indéfini.
la source
__STDC_IEC_559__
pour annoncer qu'elle est conforme à cette spécification. L'Annexe F décrit l'arithmétique en virgule flottante CEI 60559. Je crois qu'une spécification C est autorisée à se conformer partiellement à l'annexe F (par exemple pow (0, 0) == 1) et ne pas définir__STDC_IEC_559__
.C'est juste une convention de le définir comme
1
,0
ou de le laisserundefined
. La définition est largement répandue en raison de la définition suivante:La documentation ECMA-Script dit ce qui suit sur
pow(x,y)
:[ http://www.ecma-international.org/ecma-262/5.1/#sec-15.8.2.13 ]
la source
Selon Wikipedia:
Il existe plusieurs façons de traiter
0**0
chacune avec des avantages et des inconvénients (voir Wikipedia pour une discussion approfondie).La norme à virgule flottante IEEE 754-2008 recommande trois fonctions différentes:
pow
friandises0**0
comme1
. Il s'agit de la version la plus ancienne définie. Si la puissance est un entier exact, le résultat est le même que pourpown
, sinon le résultat est comme pourpowr
(sauf dans certains cas exceptionnels).pown
traite 0 ** 0 comme 1. La puissance doit être un entier exact. La valeur est définie pour les bases négatives; par exemple,pown(−3,5)
est−243
.powr
traite 0 ** 0 comme NaN (Not-a-Number - non défini). La valeur est également NaN pour les cas commepowr(−3,2)
où la base est inférieure à zéro. La valeur est définie par exp (puissance '× log (base)).la source
Donald Knuth
en quelque sorte réglé ce débat en 1992 avec ce qui suit:
Et est allé encore plus dans les détails dans son article Two Notes on Notation .
Fondamentalement, bien que nous n'ayons pas 1 comme limite de
f(x)/g(x)
pour toutes les fonctions pas toutesf(x)
etg(x)
, cela rend la combinatoire tellement plus simple à définir0^0=1
, puis faites simplement des cas spéciaux aux quelques endroits où vous devez considérer des fonctions telles que0^x
, qui sont bizarres de toute façon. Après tout, celax^0
revient beaucoup plus souvent.Certaines des meilleures discussions que je connaisse sur ce sujet (autres que l'article de Knuth) sont:
la source
Lorsque vous voulez savoir à quelle valeur vous devez donner
f(a)
quandf
n'est pas directement calculablea
, vous calculez la limite def
quandx
tend versa
.Dans le cas de
x^y
, les limites habituelles tendent vers1
quandx
ety
tendent vers0
, et surtoutx^x
vers1
quandx
tend vers0
.Voir http://www.math.hmc.edu/funfacts/ffiles/10005.3-5.shtml
la source
La définition du langage C dit (7.12.7.4/2):
Il dit aussi (7.12.1 / 2):
Par défaut, la valeur de
math_errhandling
estMATH_ERRNO
, alors vérifiezerrno
la valeurEDOM
.la source
g++ (Ubuntu/Linaro 4.8.1-10ubuntu8) 4.8.
Je ne suis pas d'accord avec certaines des réponses précédentes affirmant que c'est une question de convention ou de commodité (couvrant certains cas spéciaux pour divers théorèmes, etc.) que 0 ^ 0 soit défini comme 1 au lieu de 0.
L'exponentiation ne correspond pas vraiment à nos autres notations mathématiques, donc la définition que nous apprenons tous laisse place à la confusion. Une manière légèrement différente de l'aborder est de dire que a ^ b (ou exp (a, b), si vous voulez) renvoie la valeur multiplicative équivalente à la multiplication d' une autre chose par a, répétée b fois.
Lorsque nous multiplions 5 par 4, 2 fois, nous obtenons 80. Nous avons multiplié 5 par 16. Donc 4 ^ 2 = 16.
Lorsque vous multipliez 14 par 0, 0 fois, il nous reste 14. Nous l'avons multiplié par 1. Par conséquent, 0 ^ 0 = 1.
Cette ligne de pensée pourrait également aider à clarifier les exposants négatifs et fractionnaires. 4 ^ (- 2) est un 16e, car «multiplication négative» est une division - nous divisons par quatre deux fois.
a ^ (1/2) est la racine (a), car multiplier quelque chose par la racine de a est la moitié du travail multiplicatif que le multiplier par un lui-même - il faudrait le faire deux fois pour multiplier quelque chose par 4 = 4 ^ 1 = (4 ^ (1/2)) ^ 2
la source
Pour cela, vous devez résoudre le calcul:
En développant
x^x
autour de zéro en utilisant la série Taylor, nous obtenons:Donc, pour comprendre ce qui se passe avec la limite quand
x
va à zéro, nous devons savoir ce qui se passe avec le deuxième mandatx log(x)
, car les autres termes sontx log(x)
une certaine puissance.Nous devons utiliser la transformation:
Maintenant, après cette transformation, nous pouvons utiliser la règle de L'Hôpital , qui stipule que:
Si nous différencions cette transformation, nous obtenons:
Nous avons donc calculé que le terme
log(x)*x
s'approche de 0 lorsque x s'approche de 0. Il est facile de voir que d'autres termes consécutifs se rapprochent également de zéro et même plus rapidement que le second terme.Donc au point
x=0
, la série devient1 + 0 + 0 + 0 + ...
et donc égale à 1.la source