Math.pow(0、0)=== 1なのはなぜですか?


84

私たちは皆、000が不定であるは。

しかしjavascriptは次のように述べています。

Math.pow(0, 0) === 1 // true

およびC ++は同じことを言います:

pow(0, 0) == 1 // true

どうして?

そんなこと知ってる:

>Math.pow(0.001, 0.001)
0.9931160484209338

しかし、なぜMath.pow(0, 0)エラーをスローしないのですか?または多分NaNより良いでしょう1


3
@zzzzBov:標準の定義「a <sup> b </ sup> = exp(b ln(a))」では、未定義です。これを「limit <sub> x-> 0 </ sub> f(x)<sup> g(x)</ sup>」として定義しようとすると、「f」と「g」の両方の制限がゼロになり、不定になります。機能の選択に依存するため、値。(表記が壊れていることをお詫びします。コメントで上付き文字を取得する方法がわかりません)。
マイクシーモア

@MikeSeymour、はい、その定義では0⁰(ユニコード文字を使用)が定義されていないことは承知していますが、私のコメントを読む場合、引用は「標準的な定義」ではなく「数学の世界」を参照していることに注意してください。私が最初に言及したのはこの違いであり、このニュアンスを修正するために質問が更新されました。
zzzzBov 2013年

2
@AJMansfield Um ... a ^ 0 = 1(ゼロ以外の場合)a。
beska 2013年

これにより、確率の積に依存する関数が適切な結果を提供できるようになります。コンピュータが記号数学プロセッサであるというのは間違った考えです。C言語は現実の世界で特定の実装を持っていますが、数学の世界は理想的すぎてシリコンで実装できない場合があります。
IRTFM 2013年

26
この質問の数学バージョンの場合—「なぜ0 ^ 0 = 1を定義することが多いのですか?」— math.stackexchangeには多くの良い答えがあります:math.stackexchange.com/questions/11150/…–
PLL

回答:


78

C ++でPOW(0、0)の結果、数学的に、我々は矛盾した状況があるので、結果は基本的には、実装定義された動作ですN^0常にする必要があります1が、0^N常にあるべき0ためにN > 0あなたがいずれかの数学的にこの結果に関しては何の期待を持つべきではないのでが、。このWolframAlphaフォーラムの投稿では、もう少し詳しく説明します。

pow(0,0)結果が得られることは、国際標準1理論的根拠-プログラミング言語-Cが、IEC 60559浮動小数点演算のサポートをカバーするセクションで述べているように、多くのアプリケーションに役立ちます。

一般に、C99は、数値が役立つNaN結果を避けます。[...] pow(∞、0)とpow(0,0)の結果は両方とも1です。これは、この定義を利用できるアプリケーションがあるためです。たとえば、x(p)とy(p)がp = aでゼロになる分析関数である場合、exp(y * log(x))に等しいpow(x、y)は、pが近づくにつれて1に近づきます。 a。

C ++を更新します

leemesが正しく指摘したように、私、もともとのための参照にリンクされている複雑なバージョンのPOWながら、非複雑なことがあるバージョンの主張ドメイン・エラードラフトC ++標準はにフォールバックドラフトCの標準との両方のC99C11のセクションで7.12.7.4 POW関数段落2は言う(私の強調):

[...] xがゼロでyがゼロの場合、ドメインエラーが発生する可能性があります。[...]

私が知る限り、これはこの動作が不特定の動作であることを意味します。ビットセクションを巻き戻す7.12.1 エラー状態の処理は次のように述べています。

[...]入力引数が数学関数が定義されているドメインの外にある場合、ドメインエラーが発生します。[...]ドメインエラーの場合、関数は実装定義の値を返します。整数式math_errhandling&MATH_ERRNOがゼロ以外の場合、整数式errnoは値EDOMを取得します。[...]

あったのであれば、ドメイン・エラーこれは次のようになり、実装定義された行動が、最新バージョンの両方にgccclangの値errnoである0ことはないので、ドメイン・エラーこれらのコンパイラのために。

Javascriptを更新する

Javascriptの場合、セクションpow(x、y)のの数学オブジェクト」ECMAScript®言語仕様は、他の条件の中で次のように述べています。15.8 15.8.2.13

yが+0の場合、xがNaNであっても、結果は1になります。


1
@leemes私はページが間違っていると信じています、標準はNaNが返されるべきであると言っていません。戻り値は実装によって定義されます。あなたが信頼できる情報源ではないと主張するcplusplus.comは、実際にはここでより正確です。
interjay 2013年

@interjay私はあなたが削除された答えを意味すると思います。私はその信頼性の低さについてのみ引用し、それが反対票を説明できることを望んでいました(これは私によるものではありませんでした)。どちらのページもウィキなので、信頼性は人間で間違いを犯す編集者に依存します。;)
leemes 2013年


@ShafikYaghmour同じ質問を(削除された回答で)リンクしました。
leemes 2013年

1
@Alekフィードバックに感謝し、他の人から読みたい答えを書こうとしています。私はいつも成功するとは限りませんが、やってみます。良い質問を書くことはさらに難しく、私は一度だけそれを試みました、そして私はそれに対してずっと長く費やしました、そして私は私の答えにします。
Shafik Yaghmour 2013年

35

JavaScriptMath.powでは次のように定義されています

  • yがNaNの場合、結果はNaNになります。
  • yが+0の場合、xがNaNであっても、結果は1になります。
  • yが-0の場合、xがNaNであっても、結果は1になります。
  • xがNaNで、yがゼロ以外の場合、結果はNaNになります。
  • abs(x)> 1でyが+∞の場合、結果は+∞になります。
  • abs(x)> 1でyが-∞の場合、結果は+0になります。
  • abs(x)== 1でyが+∞の場合、結果はNaNになります。
  • abs(x)== 1でyが-∞の場合、結果はNaNになります。
  • abs(x)<1でyが+∞の場合、結果は+0になります。
  • abs(x)<1でyが-∞の場合、結果は+∞になります。
  • xが+∞でy> 0の場合、結果は+∞になります。
  • xが+∞でy <0の場合、結果は+0になります。
  • xが-∞でy> 0で、yが奇数の整数の場合、結果は-∞になります。
  • xが-∞でy> 0であり、yが奇数の整数でない場合、結果は+∞になります。
  • xが-∞でy <0で、yが奇数の整数の場合、結果は-0になります。
  • xが-∞でy <0であり、yが奇数の整数でない場合、結果は+0になります。
  • xが+0でy> 0の場合、結果は+0になります。
  • xが+0でy <0の場合、結果は+∞になります。
  • xが-0でy> 0で、yが奇数の整数の場合、結果は-0になります。
  • xが-0でy> 0であり、yが奇数の整数でない場合、結果は+0になります。
  • xが-0でy <0で、yが奇数の整数の場合、結果は-∞になります。
  • xが-0でy <0であり、yが奇数の整数でない場合、結果は+∞になります。
  • x <0でxが有限で、yが有限で、yが整数でない場合、結果はNaNになります。

強調鉱山

原則として、任意の言語のネイティブ関数は、言語仕様で説明されているように機能する必要があります。これには、結果がどうあるべきかを決定するのは実装者次第である明示的な「未定義の動作」が含まれる場合がありますが、これは未定義の動作の場合ではありません。


C99およびC11規格の付録Fには、これと同じ仕様が含まれています。実装は__STDC_IEC_559__、この仕様に準拠していることをアナウンスするように定義することになっています。付録Fは、IEC60559浮動小数点演算について説明しています。C仕様は、部分的にAnnex Fに準拠することが許可されており(たとえば、pow(0、0)== 1)、を定義することはできないと思います__STDC_IEC_559__
ハワードヒナント2013年

@HowardHinnantうーん、gccclangの場合、その情報は完全には役に立たない可能性があり、それは落胆しているようです。
Shafik Yaghmour 2013年

6
この答えが役立つかどうかはわかりません。もちろん、関数は仕様で定義されているとおりに実行する必要があります。しかし、質問は「なぜ仕様でこのように定義されたのか」ということになります。
beska 2013年

これは(おそらく)ハードウェアで行われるのは良いことです。そうしないと、これらすべての特殊なケースでパフォーマンスが低下します:)
Thomas

16

として定義するか10そのままにしておくのは単なる慣例undefinedです。この定義pow(0,0)は、次の定義のために広く普及しています。

数学的パワーの定義


ECMA-Scriptのドキュメントには、次のことが記載されていますpow(x,y)

  • yが+0の場合、xがNaNであっても、結果は1になります。
  • yが-0の場合、xがNaNであっても、結果は1になります。

[ http://www.ecma-international.org/ecma-262/5.1/#sec-15.8.2.13 ]


3
math.stackexchangeには、定義0 ^ 0 = 1に関する多くの優れた議論と説明があります:math.stackexchange.com/questions/11150/…–
PLL

14

ウィキペディアによると:

指数の連続性を含まないほとんどの設定では、0 0を1として解釈すると、式が単純化され、定理での特別な場合の必要性がなくなります。

0**0それぞれに賛否両論を扱ういくつかの可能な方法があります(詳細な議論についてはウィキペディアを参照してください)。

IEEE 754-2008浮動小数点標準は、3つの異なる機能をお勧めします。

  • pow0**0として扱います1。これは最も古い定義済みバージョンです。累乗が正確な整数の場合、結果はと同じになりますpown。それ以外の場合、結果はと同じになりますpowr(一部の例外的な場合を除く)。
  • pown0 ** 0を1として扱います。累乗は正確な整数でなければなりません。値は負の基数に対して定義されます。たとえば、pown(−3,5)です−243
  • powr0 ** 0をNaN(Not-a-Number –未定義)として扱います。powr(−3,2)底がゼロ未満の場合など、値もNaNです。値はexp(power '×log(base))で定義されます。

6

ドナルド・クヌース

1992年にこの議論を次のように解決しました。

ここに画像の説明を入力してください

そして、彼の論文「Two NotesonNotation」でさらに詳しく説明しました。

基本的に、f(x)/g(x)すべてではないすべての関数f(x)との制限として1はありませんがg(x)、それでも組み合わせ論の定義が非常に簡単に0^0=1なり、などの関数を考慮する必要があるいくつかの場所で特別なケースを作成します0^x。とにかく変です。結局のところx^0、もっと頻繁に出てきます。

このトピックについて私が知っている最高の議論のいくつか(クヌースの論文を除く)は次のとおりです。


いくつか読んでいない場合は、ゼロのゼロ乗の答えを読んでください...?これは質問からリンクされており、回答のいくつかはこのアプローチもカバーしているはずです。
Shafik Yaghmour 2013


5

C言語の定義によると(7.12.7.4/2):

xがゼロでyがゼロの場合、ドメインエラーが発生する可能性があります。

また、(7.12.1 / 2)と書かれています。

ドメインエラーの場合、関数は実装定義の値を返します。整数式math_errhandling&MATH_ERRNOがゼロ以外の場合、整数式errnoは値EDOMを取得します。整数式math_errhandling&MATH_ERREXCEPTがゼロ以外の場合、「無効な」浮動小数点例外が発生します。

デフォルトでは、の値はmath_errhandlingです。値をMATH_ERRNO確認errnoしてくださいEDOM


1
おっと!それは本当に面白いです!私が使用して私のcppファイルをコンパイルg++ (Ubuntu/Linaro 4.8.1-10ubuntu8) 4.8.
IonicăBizău

0

0 ^ 0を0ではなく1として定義するのは慣例または便宜の問題である(さまざまな定理のいくつかの特別な場合などをカバーする)という以前の回答の主張のいくつかに同意したくありません。

べき乗は実際には他の数学表記とうまく適合しないため、私たち全員が学ぶ定義には混乱の余地があります。少し異なるアプローチ方法は、a ^ b(または必要に応じてexp(a、b))が、他のものにaを掛けb回繰り返すのと同等の値を返すと言うことです。

5に4を2回掛けると、80になります。5に16を掛けたので、4 ^ 2 = 16になります。

14に0を0倍すると、14が残ります。1を掛けたので、0 ^ 0 = 1です。

この考え方は、負の指数と分数の指数を明確にするのにも役立つ可能性があります。4 ^(-2)は16番目です。これは、「負の乗算」が除算であるためです。4で2回除算します。

a ^(1/2)はroot(a)です。これは、何かにaのルートを掛けることは、それ自体を掛ける場合の半分の乗法作業であるためです。何かを4 = 4 ^ 1 =で掛けるには、2回行う必要があります。 (4 ^(1/2))^ 2


0

これを理解するには、微積分を解く必要があります。

ここに画像の説明を入力してください

x^xテイラー級数を使用してゼロ付近を展開すると、次のようになります。

ここに画像の説明を入力してください

したがって、xゼロになったときに制限で何が起こっているのかを理解するにはx log(x)、他の項がに比例するため、第2項で何が起こっているのかを知る必要があります。x log(x)あるべき乗にです。

変換を使用する必要があります。

ここに画像の説明を入力してください

この変換の後、次のように述べているロピタルの定理を使用できます。

ここに画像の説明を入力してください

その変換を差別化することで、次のことが可能になります。

ここに画像の説明を入力してください

だから私たちはその用語を計算しました log(x)*x、xが0に近づくが0に近づくとた。他の連続する項もゼロに近づき、2番目の項よりもさらに速くなることは簡単にわかります。

したがって、ポイントでx=0、シリーズは1 + 0 + 0 + 0 + ...1になり、したがって1に等しくなります。


この答えは印象的ですが、数学では、関数がxで連続でない限り、f(x)のx-> aとしての制限は必ずしもf(a)と等しくないことに注意してください。
jasonszhao 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.