web-dev-qa-db-fra.com

Pourquoi Math.pow (0, 0) === 1?

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.

84
Ionică Bizău

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.

78
Shafik Yaghmour

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.

35
zzzzBov

C'est juste une convention de le définir comme 1, 0 Ou de le laisser undefined. La définition pow(0,0) est largement répandue en raison de la définition suivante:

mathematical power definition


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 ]

16
schmijos

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)).
14
NPE

Donald Knuth

sorte de régler ce débat en 1992 avec ce qui suit:

enter image description here

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:

6
Thomas Ahle

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.

5
Pete Becker

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

5
Denys Séguret

Pour comprendre cela, vous devez résoudre le calcul:

enter image description here

En développant x^x Autour de zéro en utilisant la série Taylor, nous obtenons:

enter image description here

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:

enter image description here

Maintenant, après cette transformation, nous pouvons utiliser la règle de L'Hôpital , qui stipule que:

enter image description here

Donc, en différenciant cette transformation, nous obtenons:

enter image description here

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.

0

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

0
NiloCK