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


85

Hepimiz biliyoruz ki 0 0 belirsiz .

Ancak , javascript şunu söylüyor:

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

ve C ++ aynı şeyi söylüyor:

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

NEDEN?

Bunu biliyorum:

>Math.pow(0.001, 0.001)
0.9931160484209338

Ama neden Math.pow(0, 0)hiç hata yapmıyor ? Ya da belki a NaNdaha iyi olabilir 1.


3
@zzzzBov: "a <sup> b </sup> = exp (b ln (a))" standart tanımına göre tanımsızdır. Bunu "limit <sub> x-> 0 </sub> f (x) <sup> g (x) </sup>" olarak tanımlamaya çalışmak, burada "f" ve "g" nin her ikisinin de sıfır limitleri vardır değer, çünkü işlev seçiminize bağlıdır. (Karışık gösterimler için özür dilerim; yorumlarda üst simgelerin nasıl alınacağını çözemiyorum).
Mike Seymour

@MikeSeymour, evet, 0⁰'nin (unicode karakterleri kullanın) bu tanıma göre tanımsız olduğunun farkındayım, ancak, eğer yorumumu okursanız, alıntı herhangi bir "standart tanım" yerine "matematik dünyasına" atıfta bulunmalıdır. Başlangıçta bahsettiğim bu fark ve soru bu nüansı düzeltmek için güncellendi.
zzzzBov

2
@AJMansfield Um ... a ^ 0 = 1 için sıfır olmayan a.
Beska

Olasılık ürünlerine bağlı işlevlerin mantıklı sonuçlar vermesine izin verir. Bilgisayarların sembolik matematik işlemcileri olduğu yanlış bir görüş. C dilinin gerçek dünyada belirli bir uygulaması varken, matematiksel dünyanız silikonda uygulanmak için fazla ideal olabilir.
IRTFM

26
Bu sorunun matematiksel versiyonu için - "neden genellikle 0 ^ 0 = 1 tanımlıyoruz?" - math.stackexchange'in pek çok iyi yanıtı var: math.stackexchange.com/questions/11150/…
PLL

Yanıtlar:


78

C ++ pow (0, 0) sonucu sonucu matematiksel bir çelişkili durum var çünkü davranışını tanımlanan uygulama temelde N^0her zaman olmalı 1ama 0^Nher zaman olması gerektiği 0için N > 0ya bu sonucu olarak matematiksel olarak beklentim yok bu yüzden. Bu Wolfram Alpha forum gönderileri biraz daha ayrıntıya giriyor.

IEC 60559 kayan noktalı aritmetik desteğini kapsayan bölümde Uluslararası Standart - Programlama Dilleri - C'nin gerekçesinde belirtildiği gibi birçok uygulama için pow(0,0)sonuca sahip 1olmak yararlı olsa da :

Genel olarak, C99, sayısal bir değerin yararlı olduğu bir NaN sonucundan kaçınır. [...] pow (∞, 0) ve pow (0,0) sonuçlarının her ikisi de 1'dir, çünkü bu tanımdan yararlanabilecek uygulamalar vardır. Örneğin, x (p) ve y (p), p = a'da sıfır olan herhangi bir analitik fonksiyonsa, exp (y * log (x)) 'e eşit olan pow (x, y), p yaklaştıkça 1'e yaklaşır. a.

C ++ güncelleyin

Leemes doğru işaret edildiği gibi başlangıçta referans ile bağlantılı kompleks sürümüne POW ise , karmaşık olmayan o versiyon istemlerden alan hata taslak C ++ standart geri döner taslak Cı standart ve her iki C99 ve C11 bölümünde 7.12.7.4 pow fonksiyonları paragraf 2 diyor ( vurgu benim ):

[...] x sıfır ve y sıfırsa bir alan hatası oluşabilir . [...]

Anlayabildiğim kadarıyla bu davranışın tanımlanmamış bir davranış olduğu anlamına gelir Biraz geri sarma Bölüm 7.12.1 Hata durumlarının tedavisi şöyle der:

[...] bir girdi bağımsız değişkeni matematiksel işlevin tanımlandığı etki alanının dışındaysa bir etki alanı hatası oluşur. [...] Etki alanı hatasında işlev, uygulama tanımlı bir değer döndürür; math_errhandling & MATH_ERRNO tamsayı ifadesi sıfır değilse, errno tamsayı ifadesi EDOM değerini alır; [...]

Bir varsa Yani alanı hatası o zaman bu olurdu uygulama tanımlı davranış ama son sürümlerinde hem de gccve clangdeğeri errnoolan 0bir değil bu yüzden alanı hatası bu derleyiciler için.

Javascript'i güncelle

İçin JavaScript ECMAScript® Dil Şartname bölümünde 15.8 Matematik Nesne altında 15.8.2.13 pow (x, y) diğer koşullara o aralarında diyor ki:

Y +0 ise, x NaN olsa bile sonuç 1'dir.


1
@leemes Sayfanın yanlış olduğuna inanıyorum, standart NaN'nin döndürülmesi gerektiğini söylemiyor. Dönüş değeri uygulama tanımlıdır. Güvenilir bir kaynak olmadığını iddia ettiğiniz cplusplus.com aslında burada daha doğru.
interjay

@interjay Sanırım silinmiş yanıtı kastettiniz; Sadece güvenilmezliği hakkında alıntı yaptım, olumsuz oyu açıklayabileceğini umdum (ki bu benim tarafımdan yapılmadı). Her iki sayfa da wiki'dir, bu nedenle güvenilirlikleri insan olan ve hata yapan editörlerine bağlıdır. ;)
leemes


@ShafikYaghmour Aynı soruyu bağladım (silinmiş cevapta).
leemes

1
@Alek Geri bildirimi takdir ediyorum, başkalarından okumak istediğim cevapları yazmaya çalışıyorum. Her zaman başarılı olamıyorum ama deniyorum. İyi sorular yazmak daha da zor, bunu sadece bir kez denedim ve cevaplarıma göre çok daha uzun süre uğraştım.
Shafik Yaghmour

35

JavaScript'te Math.powşu şekilde tanımlanır :

  • Y NaN ise, sonuç NaN olur.
  • Y +0 ise, x NaN olsa bile sonuç 1'dir.
  • Y -0 ise, x NaN olsa bile sonuç 1'dir.
  • X NaN ise ve y sıfır değilse, sonuç NaN olur.
  • Abs (x)> 1 ve y + ∞ ise, sonuç + ∞ olur.
  • Abs (x)> 1 ve y -∞ ise sonuç +0 olur.
  • Abs (x) == 1 ve y + ∞ ise sonuç NaN olur.
  • Abs (x) == 1 ve y -∞ ise sonuç NaN olur.
  • Abs (x) <1 ve y + ∞ ise, sonuç +0 olur.
  • Abs (x) <1 ve y -∞ ise, sonuç + ∞ olur.
  • X + ∞ ve y> 0 ise sonuç + ∞ olur.
  • X + ∞ ve y <0 ise sonuç +0 olur.
  • X --∞ ve y> 0 ve y tek bir tam sayı ise, sonuç --∞ olur.
  • X - ∞ ise ve y> 0 ve y tek bir tam sayı değilse, sonuç + ∞ olur.
  • X --∞ ve y <0 ve y tek bir tam sayı ise, sonuç -0 olur.
  • X - ∞ ise ve y <0 ve y tek bir tam sayı değilse, sonuç +0 olur.
  • X +0 ve y> 0 ise sonuç +0 olur.
  • X +0 ve y <0 ise sonuç + ∞ olur.
  • X -0 ve y> 0 ve y tek bir tamsayı ise, sonuç -0 olur.
  • X -0 ve y> 0 ise ve y tek bir tam sayı değilse, sonuç +0 olur.
  • X -0 ve y <0 ve y tek bir tamsayı ise, sonuç -∞ olur.
  • X -0 ve y <0 ise ve y tek bir tam sayı değilse, sonuç + ∞ olur.
  • X <0 ve x sonlu ve y sonlu ve y bir tam sayı değilse, sonuç NaN olur.

benim vurgu

genel bir kural olarak, herhangi bir dilin yerel işlevleri, dil belirtiminde açıklandığı gibi çalışmalıdır. Bazen bu, sonucun ne olacağına karar vermenin uygulayıcıya bağlı olduğu açık bir şekilde "tanımlanmamış davranışı" içerir, ancak bu tanımsız bir davranış durumu değildir.


C99 ve C11 standartlarındaki Ek F, aynı spesifikasyonu içerir. Bir uygulamanın, __STDC_IEC_559__bu şartnameye uygun olduğunu bildirmek için tanımlaması beklenir . Ek F, IEC 60559 kayan nokta aritmetiğini açıklar. Bir C spesifikasyonunun Ek F'ye kısmen uymasına izin verildiğine (örneğin, pow (0, 0) == 1) ve tanımlamadığına inanıyorum __STDC_IEC_559__.
Howard Hinnant

@HowardHinnant hmmm, gcc ve clang söz konusu olduğunda bu bilgi parçası tamamen yardımcı olmayabilir, bu cesaret kırıcı.
Shafik Yaghmour

6
Bu cevabın yardımcı olduğunu bilmiyorum. Elbette işlev, şartnamede tanımlandığı gibi çalışmalıdır. Ama sonra soru sadece "Şartnamede neden bu şekilde tanımlandı?"
Beska

İyi bir şey (muhtemelen) donanımda yapılır, aksi takdirde tüm bu özel durumlarda performansı düşürür :)
Thomas

16

Olarak tanımlamak sadece kongre olduğunu 1, 0ya da bırakın undefined. Tanım pow (0,0), aşağıdaki tanım nedeniyle geniş bir alana yayılmıştır:

matematiksel güç tanımı


ECMA-Script belgeleri şunlarla ilgili olarak şunları söylüyor pow(x,y):

  • Y +0 ise, x NaN olsa bile sonuç 1'dir.
  • Y -0 ise, x NaN olsa bile sonuç 1'dir.

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


3
math.stackexchange, 0 ^ 0 = 1 tanımı için pek çok iyi tartışma ve açıklama içeriyor
PLL

14

Wikipedia'ya göre:

Üsde süreklilik içermeyen çoğu durumda, 0 0'ı 1 olarak yorumlamak formülleri basitleştirir ve teoremlerdeki özel durumlar ihtiyacını ortadan kaldırır.

Her 0**0birinin artılarını ve eksilerini ele almanın birkaç olası yolu vardır ( genişletilmiş tartışma için Wikipedia'ya bakın ).

IEEE 754-2008 kayan noktalı standart üç farklı fonksiyon önermektedir:

  • powdavranır 0**0olarak 1. Bu, tanımlanmış en eski versiyondur. Kuvvet tam bir tamsayı ise, sonuç için olanla aynıdır pown, aksi takdirde sonuç olduğu gibidir powr(bazı istisnai durumlar hariç).
  • pown0 ** 0'ı 1 olarak kabul eder. Kuvvet tam bir tam sayı olmalıdır. Değer, negatif tabanlar için tanımlanır; örneğin pown(−3,5)olduğunu −243.
  • powr0 ** 0'ı NaN (Sayı Değil - tanımsız) olarak ele alır. Değer, powr(−3,2)tabanın sıfırdan küçük olduğu durumlar için de NaN'dir . Değer exp (güç '× log (taban)) ile tanımlanır.

6

Donald Knuth

Bu tartışmayı 1992'de şu şekilde çözdü:

görüntü açıklamasını buraya girin

Ve Notasyon Üzerine İki Not adlı makalesinde daha fazla ayrıntıya girdi .

Temel olarak, f(x)/g(x)tüm işlevler için sınır olarak 1'e sahip olmasak da f(x)ve g(x)bu, kombinatorikleri tanımlamayı çok daha basit hale getiriyor 0^0=1ve sonra, göz önünde bulundurmanız gereken birkaç yerde özel durumlar 0^xoluşturuyor: zaten tuhaflar. Sonuçta x^0çok daha sık ortaya çıkıyor.

Bu konuyla ilgili bildiğim en iyi tartışmalardan bazıları (Knuth makalesi dışında):


Sıfırın sıfır kuvvetinin yanıtlarını okumadıysanız ...? Soruyla bağlantılı olan cevaplardan bazılarının da bu yaklaşımı kapsaması gerekir.
Shafik Yaghmour


5

C dili tanımı (7.12.7.4/2) diyor ki:

X sıfırsa ve y sıfırsa bir etki alanı hatası oluşabilir.

Ayrıca (7.12.1 / 2) diyor ki:

Bir etki alanı hatasında işlev, uygulama tanımlı bir değer döndürür; math_errhandling & MATH_ERRNO tamsayı ifadesi sıfır değilse, errno tamsayı ifadesi EDOM değerini alır; math_errhandling & MATH_ERREXCEPT tamsayı ifadesi sıfır değilse, "geçersiz" kayan nokta istisnası ortaya çıkar.

Varsayılan olarak değeri ' math_errhandlingdir MATH_ERRNO, bu nedenle errnodeğeri kontrol edin EDOM.


1
Whoups! Bu gerçekten ilginç! g++ (Ubuntu/Linaro 4.8.1-10ubuntu8) 4.8.
Cpp dosyamı

0

Önceki cevaplardan bazılarının, 0 ^ 0'ın 0 yerine 1 olarak tanımlanmasının (çeşitli teoremler için bazı özel durumları kapsayan) bir konvansiyon veya kolaylık meselesi olduğu iddiasına katılmamak istiyorum.

Üs alma aslında diğer matematiksel notasyonlarımıza pek uymuyor, bu yüzden hepimizin öğrendiği tanım kafa karışıklığına yer bırakıyor. Bunu yaklaşan bir az farklı yolu ^ b (veya exp (a, b), isterseniz) değeri döndürür yani multiplicatively eşdeğer çarparak için başka bir şey zamanlarda b tekrarlanan bir tarafından.

5'i 4 ile 2 çarptığımızda 80 elde ederiz. 5'i 16 ile çarptık. Yani 4 ^ 2 = 16.

14'ü 0 ile çarptığınızda, geriye 14 kalıyoruz. Onu 1'i çarptık. Dolayısıyla, 0 ^ 0 = 1.

Bu düşünce tarzı, negatif ve kesirli üsleri netleştirmeye de yardımcı olabilir. 4 ^ (- 2) 16'ncıdır, çünkü 'negatif çarpma' bölmedir - dörde iki kez böleriz.

a ^ (1/2) kök (a) 'dır, çünkü bir şeyi a'nın kökü ile çarpmak çarpımsal işin yarısıdır, onu a'nın kendisiyle çarpmaktır - bir şeyi 4 = 4 ^ 1 = ile çarpmak için bunu iki kez yapmanız gerekir. (4 ^ (1/2)) ^ 2


0

Bunu anlamak için hesabı çözmeniz gerekir:

görüntü açıklamasını buraya girin

x^xTaylor serisini kullanarak sıfır civarında genişleyerek şunu elde ederiz:

görüntü açıklamasını buraya girin

Yani xsıfıra gittiğinde limitle neler olup bittiğini anlamak için ikinci terimde neler olup bittiğini bulmalıyız x log(x)çünkü diğer terimler ile orantılıdır.x log(x) bir güce yükseltilmekle .

Dönüşümü kullanmamız gerekiyor:

görüntü açıklamasını buraya girin

Şimdi bu dönüşümden sonra L'Hôpital'in şu kuralını kullanabiliriz :

görüntü açıklamasını buraya girin

Bu dönüşümü farklılaştırarak elde ederiz:

görüntü açıklamasını buraya girin

Bu yüzden bu terimi hesapladık log(x)*x , x 0'a yaklaştığında 0'a yaklaştığını Diğer ardışık terimlerin de sıfıra yaklaştığını ve hatta ikinci terimden daha hızlı olduğunu görmek kolaydır.

Yani noktada x=0seri olur 1 + 0 + 0 + 0 + ...ve dolayısıyla 1'e eşittir.


Bu cevap etkileyici olsa da, matematikte, f (x) 'in x-> a sınırının, fonksiyon x'de sürekli olmadığı sürece, f (a)' ya eşit olması gerekmediğini belirtmek gerekir.
jasonszhao
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.