Nous savons tous que 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 Math.pow(0, 0)
ne génère-t-il aucune erreur? Ou peut-être qu'un NaN
serait mieux que 1
.
En C++ Le résultat de pow (0, 0) le résultat est essentiellement un comportement défini par l'implémentation, car mathématiquement nous avons une situation contradictoire où N^0
devrait toujours être 1
mais 0^N
devrait toujours être 0
pour N > 0
, Vous ne devriez donc avoir aucune attente mathématique quant au résultat. Ce Wolfram Alpha messages du forum va dans un peu plus de détails.
Bien qu'avoir pow(0,0)
résultat dans 1
Est utile pour de nombreuses applications comme le Justification de la norme internationale — Langages de programmation — C indique dans la section couvrant CEI 60559 arithmétique à virgule flottante support:
Généralement, C99 évite un résultat NaN lorsqu'une valeur numérique est utile. [...] Les résultats de pow (∞, 0) et pow (0,0) sont tous deux 1, car il existe des applications qui peuvent exploiter cette définition. Par exemple, si x(p) et y(p) sont des fonctions analytiques qui deviennent nulles à p = a, alors pow (x, y) , qui équivaut à exp (y * log (x)), approche 1 comme p approche a.
Mettre à jour C++
Comme les leèmes l'ont correctement souligné, j'ai à l'origine lié à la référence pour la version complexe de pow tandis que la version non complexe le prétend erreur de domaine le projet de norme C++ revient au projet de norme C et les deux C99 et C11 dans la section 7.12.7.4
Les fonctions de pow paragraphe 2 dit ( c'est le mien):
[...] Une erreur de domaine peut se produire si x est nul et y est nul. [...]
ce qui, pour autant que je sache, signifie que ce comportement est comportement non spécifié En remontant un peu la section 7.12.1
Traitement des conditions d'erreur dit:
[...] une erreur de domaine se produit si un argument d'entrée est en dehors du domaine sur lequel la fonction mathématique est définie. [...] En cas d'erreur de domaine, la fonction renvoie une valeur définie par l'implémentation; si l'expression entière math_errhandling & MATH_ERRNO est différente de zéro, l'expression entière errno acquiert la valeur EDOM; [...]
Donc, s'il y avait une erreur domaine alors ce serait comportement défini par l'implémentation mais dans les deux dernières versions de gcc
et clang
la valeur de errno
est 0
donc ce n'est pas une erreur domaine pour ces compilateurs.
Mettre à jour Javascript
Pour Javascript le Spécification du langage ECMAScript® dans la section 15.8
L'objet mathématique sous 15.8.2.13
pow (x, y) dit entre autres conditions que:
Si y est +0, le résultat est 1, même si x est NaN.
En JavaScript Math.pow
est défini comme suit :
- Si y est NaN, le résultat est NaN.
- Si y est +0, le résultat est 1, même si x est NaN.
- Si y est −0, le résultat est 1, même si x est NaN.
- Si x est NaN et y est non nul, le résultat est NaN.
- Si abs (x)> 1 et y est + ∞, le résultat est + ∞.
- Si abs (x)> 1 et y est −∞, le résultat est +0.
- Si abs (x) == 1 et y est + ∞, le résultat est NaN.
- Si abs (x) == 1 et y est −∞, le résultat est NaN.
- Si abs (x) <1 et y est + ∞, le résultat est +0.
- Si abs (x) <1 et y est −∞, le résultat est + ∞.
- Si x est + ∞ et y> 0, le résultat est + ∞.
- Si x est + ∞ et y <0, le résultat est +0.
- Si x est −∞ et y> 0 et y est un entier impair, le résultat est −∞.
- Si x est −∞ et y> 0 et y n'est pas un entier impair, le résultat est + ∞.
- Si x est −∞ et y <0 et y est un entier impair, le résultat est −0.
- Si x est −∞ et y <0 et y n'est pas un entier impair, le résultat est +0.
- Si x est +0 et y> 0, le résultat est +0.
- Si x est +0 et y <0, le résultat est + ∞.
- Si x est −0 et y> 0 et y est un entier impair, le résultat est −0.
- Si x est −0 et y> 0 et y n'est pas un entier impair, le résultat est +0.
- Si x est −0 et y <0 et y est un entier impair, le résultat est −∞.
- Si x est −0 et y <0 et y n'est pas un entier impair, le résultat est + ∞.
- Si x <0 et x est fini et y est fini et y n'est pas un entier, le résultat est NaN.
mettre l'accent
en règle générale, les fonctions natives de n'importe quelle langue devraient fonctionner comme décrit dans la spécification de langue. Parfois, cela inclut explicitement un "comportement indéfini" où il appartient à l'implémenteur de déterminer quel devrait être le résultat, mais ce n'est pas un cas de comportement indéfini.
C'est juste une convention de le définir comme 1
, 0
Ou de le laisser undefined
. La définition est largement répandue en raison de la définition suivante:
La documentation ECMA-Script indique ce qui suit à propos de pow(x,y)
:
- Si y est +0, le résultat est 1, même si x est NaN.
- Si y est −0, le résultat est 1, même si x est NaN.
[ http://www.ecma-international.org/ecma-262/5.1/#sec-15.8.2.1 ]
Selon Wikipedia:
Dans la plupart des contextes n'impliquant pas de continuité dans l'exposant, l'interprétation 0 as 1 simplifie les formules et élimine le besoin de cas spéciaux dans les théorèmes.
Il existe plusieurs façons possibles de traiter 0**0
Avec des avantages et des inconvénients pour chacun (voir Wikipedia pour une discussion approfondie).
La norme IEEE 754-2008 virgule flottante recommande trois fonctions différentes:
pow
traite 0**0
comme 1
. Il s'agit de la version définie la plus ancienne. Si la puissance est un entier exact, le résultat est le même que pour pown
, sinon le résultat est comme pour powr
(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 comme powr(−3,2)
où la base est inférieure à zéro. La valeur est définie par exp (puissance '× log (base)).sorte de régler 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 f(x)
et g(x)
pas toutes, cela rend la combinatoire tellement plus simple à définir 0^0=1
, puis créez des cas spéciaux dans les quelques endroits où vous devez considérer des fonctions telles que 0^x
, qui sont quand même bizarres. Après tout x^0
revient beaucoup plus souvent.
Certaines des meilleures discussions que je connaisse sur ce sujet (autres que l'article de Knuth) sont:
La définition du langage C dit (7.12.7.4/2):
Une erreur de domaine peut se produire si x est nul et y est nul.
Il dit également (7.12.1/2):
En cas d'erreur de domaine, la fonction renvoie une valeur définie par l'implémentation; si l'expression entière math_errhandling & MATH_ERRNO est différente de zéro, l'expression entière errno acquiert la valeur EDOM; si l'expression entière math_errhandling & MATH_ERREXCEPT est différente de zéro, l'exception à virgule flottante "invalide" est levée.
Par défaut, la valeur de math_errhandling
est MATH_ERRNO
, vérifiez donc errno
pour la valeur EDOM
.
Lorsque vous voulez savoir quelle valeur vous devez donner à f(a)
lorsque f
n'est pas directement calculable dans a
, vous calculez la limite de f
lorsque x
tend vers a
.
En cas de x^y
, les limites habituelles tendent vers 1
lorsque x
et y
ont tendance à 0
, et particulièrement x^x
tend vers 1
lorsque x
tend à 0
.
Voir http://www.math.hmc.edu/funfacts/ffiles/10005.3-5.shtml
Pour comprendre 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 une limite lorsque x
passe à zéro, nous devons savoir ce qui se passe avec le deuxième terme x log(x)
, car les autres termes sont proportionnels à x log(x)
élevé à un certain pouvoir.
Nous devons utiliser la transformation:
Maintenant, après cette transformation, nous pouvons utiliser la règle de L'Hôpital , qui stipule que:
Donc, en différenciant cette transformation, nous obtenons:
Nous avons donc calculé que le terme log(x)*x
approche 0 lorsque x approche 0. Il est facile de voir que d'autres termes consécutifs approchent également zéro et même plus rapidement que le deuxième terme.
Donc, au point x=0
, La série devient 1 + 0 + 0 + 0 + ...
Et est donc égale à 1.
Je ne suis pas d'accord avec certaines affirmations des réponses précédentes selon lesquelles 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 façon légèrement différente de l'approcher est de dire que a ^ b (ou exp (a, b), si vous le souhaitez) renvoie la valeur équivalent multiplicatif à multiplier autre chose = par a, répété 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, nous nous retrouvons avec 14. Nous l'avons multiplié 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 la "multiplication négative" est la division - nous divisons par quatre deux fois.
a ^ (1/2) est racine (a), parce que multiplier quelque chose par la racine de a est la moitié de travail multiplicatif comme le multipliant par un lui-même - vous devrez le faire deux fois pour multiplier quelque chose par 4 = 4 ^ 1 = (4 ^ (1/2)) ^ 2