เหตุใด Math.pow (0, 0) === 1


85

เราทุกคนรู้ดีว่า 0 0นั้นไม่แน่นอน

แต่ , จาวาสคริปต์กล่าวว่า:

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

และC ++พูดในสิ่งเดียวกัน:

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

ทำไม?

ฉันรู้แล้ว:

>Math.pow(0.001, 0.001)
0.9931160484209338

แต่ทำไมการMath.pow(0, 0)โยนไม่มีข้อผิดพลาด? หรืออาจจะดีกว่าNaN1


3
@zzzzBov: ภายใต้คำจำกัดความมาตรฐาน "a <sup> b </sup> = exp (b ln (a))" จะไม่ได้กำหนดไว้ การพยายามกำหนดเป็น "ขีด จำกัด <sub> x-> 0 </sub> f (x) <sup> g (x) </sup>" โดยที่ "f" และ "g" ทั้งสองมีขีด จำกัด เป็นศูนย์จะทำให้ไม่แน่นอน มูลค่าเนื่องจากขึ้นอยู่กับฟังก์ชันที่คุณเลือก (ขออภัยสำหรับสัญกรณ์ที่สับสนฉันไม่สามารถหาวิธีรับตัวยกในความคิดเห็นได้)
Mike Seymour

@MikeSeymour ใช่ฉันทราบว่า0⁰ (ใช้อักขระ Unicode) ไม่ได้กำหนดตามคำจำกัดความนั้นอย่างไรก็ตามหากคุณอ่านความคิดเห็นของฉันคุณควรทราบว่าใบเสนอราคาอ้างอิงถึง "โลกแห่งคณิตศาสตร์" มากกว่า "คำจำกัดความมาตรฐาน" ใด ๆ นี่คือความแตกต่างที่ฉันอ้างถึงในตอนแรกและคำถามได้รับการอัปเดตเพื่อแก้ไขความแตกต่างเล็กน้อยนี้
zzzzBov

2
@AJMansfield อืม ... a ^ 0 = 1 สำหรับ non-zero a.
Beska

ช่วยให้ฟังก์ชันที่ขึ้นอยู่กับผลคูณของความน่าจะเป็นเพื่อให้ได้ผลลัพธ์ที่สมเหตุสมผล เป็นความคิดที่ไม่ถูกต้องว่าคอมพิวเตอร์เป็นตัวประมวลผลทางคณิตศาสตร์เชิงสัญลักษณ์ ภาษาซีมีการใช้งานเฉพาะในโลกแห่งความเป็นจริงในขณะที่โลกทางคณิตศาสตร์ของคุณอาจเหมาะเกินกว่าที่จะนำมาใช้ในซิลิคอน
IRTFM

26
สำหรับคำถามในรูปแบบทางคณิตศาสตร์ -“ ทำไมเรามักกำหนด 0 ^ 0 = 1?” - math.stackexchange มีคำตอบดีๆมากมาย: math.stackexchange.com/questions/11150/…
PLL

คำตอบ:


78

ใน C ++ ผลมาจากธาร (0, 0)ผลที่ได้คือโดยทั่วไปการดำเนินการกำหนดพฤติกรรมตั้งแต่ทางคณิตศาสตร์เรามีสถานการณ์ขัดแย้งที่N^0ควรจะเป็น1แต่0^Nควรจะเป็น0สำหรับN > 0ดังนั้นคุณควรจะมีความคาดหวังทางคณิตศาสตร์เพื่อผลจากการนี้อย่างใดอย่างหนึ่ง โพสต์ในฟอรัมWolfram Alphaนี้มีรายละเอียดเพิ่มเติมเล็กน้อย

แม้ว่าการมีpow(0,0)ผลลัพธ์1จะมีประโยชน์สำหรับแอปพลิเคชันต่างๆเนื่องจากเหตุผลสำหรับมาตรฐานสากล - ภาษาการเขียนโปรแกรม -สถานะCในส่วนที่ครอบคลุมการสนับสนุนเลขคณิตลอยตัวของ IEC 60559 :

โดยทั่วไป C99 จะหลีกเลี่ยงผลลัพธ์ NaN ซึ่งค่าตัวเลขมีประโยชน์ [... ] ผลลัพธ์ของพาว (∞, 0) และพาว (0,0) เป็น 1 ทั้งคู่เนื่องจากมีแอพพลิเคชั่นที่สามารถใช้ประโยชน์จากความหมายนี้ได้ ตัวอย่างเช่นถ้า x (p) และ y (p) เป็นฟังก์ชันการวิเคราะห์ใด ๆ ที่กลายเป็นศูนย์ที่ p = a แล้วก็พาว (x, y) ซึ่งเท่ากับ exp (y * log (x)) เข้าใกล้ 1 เป็น p เข้าใกล้ ก.

อัปเดต C ++

ในฐานะที่เป็น leemes ชี้ได้อย่างถูกต้องจากฉันเดิมที่เชื่อมโยงกับการอ้างอิงสำหรับซับซ้อนรุ่นของธารในขณะที่ที่ไม่ซับซ้อนเรียกร้องรุ่นมันเป็นข้อผิดพลาดโดเมนร่าง c ++ มาตรฐานตกกลับไปที่ร่างมาตรฐาน Cและทั้งสองC99และC11ในส่วน7.12.7.4 ฟังก์ชั่นธารวรรค2พูดว่า ( เน้นของฉัน ):

[... ] ข้อผิดพลาดของโดเมนอาจเกิดขึ้นถ้า x เป็นศูนย์และ y เป็นศูนย์ [... ]

ซึ่งเท่าที่ฉันสามารถบอกได้หมายความว่าพฤติกรรมนี้เป็นพฤติกรรมที่ไม่ได้ระบุการย้อนกลับส่วนบิต7.12.1 การรักษาเงื่อนไขข้อผิดพลาดกล่าวว่า:

[... ] ข้อผิดพลาดของโดเมนเกิดขึ้นหากอาร์กิวเมนต์อินพุตอยู่นอกโดเมนซึ่งฟังก์ชันทางคณิตศาสตร์ถูกกำหนดไว้ [... ] ในข้อผิดพลาดของโดเมนฟังก์ชันจะส่งคืนค่าที่กำหนดโดยการนำไปใช้งาน ถ้านิพจน์จำนวนเต็ม math_errhandling & MATH_ERRNO ไม่ใช่ศูนย์นิพจน์จำนวนเต็มจะไม่ได้รับค่า EDOM [... ]

ดังนั้นหากมีข้อผิดพลาดของโดเมนสิ่งนี้จะเป็นพฤติกรรมที่กำหนดการนำไปใช้แต่ในทั้งเวอร์ชันล่าสุดgccและclangค่าของerrnoคือ0ดังนั้นจึงไม่ใช่ข้อผิดพลาดของโดเมนสำหรับคอมไพเลอร์เหล่านั้น

อัปเดต Javascript

สำหรับJavascriptข้อกำหนดภาษาECMAScript®ในส่วน15.8 The Math Objectภายใต้15.8.2.13 pow (x, y)กล่าวในเงื่อนไขอื่น ๆ ที่:

ถ้า y คือ +0 ผลลัพธ์คือ 1 แม้ว่า x จะเป็น NaN


1
@leemes เชื่อว่าเพจผิดมาตรฐานไม่ได้บอกว่าควรคืน NaN ค่าที่ส่งคืนถูกกำหนดโดยการนำไปใช้งาน cplusplus.com ที่คุณอ้างว่าไม่ใช่แหล่งข้อมูลที่เชื่อถือได้นั้นถูกต้องกว่าที่นี่
interjay

@interjay ฉันเดาว่าคุณหมายถึงคำตอบที่ถูกลบ ฉันอ้างถึงความไม่น่าเชื่อถือของมันเท่านั้นหวังว่ามันจะสามารถอธิบายการโหวตลด (ซึ่งไม่ใช่ของฉัน) ทั้งสองหน้าเป็นวิกิดังนั้นความน่าเชื่อถือจึงขึ้นอยู่กับผู้แก้ไขซึ่งเป็นมนุษย์และทำผิดพลาด ;)
leemes


@ShafikYaghmour ฉันเชื่อมโยงคำถามเดียวกัน (ในคำตอบที่ถูกลบ)
leemes

1
@Alek ฉันขอขอบคุณสำหรับข้อเสนอแนะฉันพยายามเขียนคำตอบที่ฉันต้องการอ่านจากคนอื่น ฉันไม่เคยประสบความสำเร็จ แต่ฉันพยายาม การเขียนคำถามที่ดีนั้นยากยิ่งกว่าฉันได้ลองเพียงครั้งเดียวและฉันก็ใช้เวลานานขึ้นกับคำถามนั้น
Shafik Yaghmour

35

ใน JavaScript Math.powถูกกำหนดไว้ดังนี้ :

  • ถ้า y คือ NaN ผลลัพธ์คือ NaN
  • ถ้า y คือ +0 ผลลัพธ์คือ 1 แม้ว่า x จะเป็น NaN
  • ถ้า y คือ −0 ผลลัพธ์คือ 1 แม้ว่า x จะเป็น NaN
  • ถ้า 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

เน้นของฉัน

ตามกฎทั่วไปฟังก์ชันดั้งเดิมของภาษาใด ๆ ควรทำงานตามที่อธิบายไว้ในข้อกำหนดภาษา บางครั้งสิ่งนี้รวมถึง "พฤติกรรมที่ไม่ได้กำหนด" อย่างชัดเจนซึ่งขึ้นอยู่กับผู้ดำเนินการที่จะพิจารณาว่าผลลัพธ์ควรเป็นอย่างไรอย่างไรก็ตามนี่ไม่ใช่กรณีของพฤติกรรมที่ไม่ได้กำหนด


ภาคผนวก F ในมาตรฐาน C99 และ C11 ประกอบด้วยข้อกำหนดเดียวกันนี้ การใช้งานควรกำหนด__STDC_IEC_559__เพื่อประกาศว่าเป็นไปตามข้อกำหนดนี้ ภาคผนวก F อธิบายเลขคณิตทศนิยมของ IEC 60559 ผมเชื่อว่าสเปค C ได้รับอนุญาตให้บางส่วนเป็นไปตามภาคผนวก F (เช่นธาร (0, 0) == 1) __STDC_IEC_559__และได้กำหนด
Howard Hinnant

@HowardHinnant อืมดูเหมือนว่าในกรณีของgccและเสียงดังข้อมูลชิ้นนั้นอาจไม่เป็นประโยชน์เลยนั่นเป็นเรื่องที่น่าท้อใจ
Shafik Yaghmour

6
ฉันไม่รู้ว่าคำตอบนี้ช่วยได้ แน่นอนว่าฟังก์ชันควรทำงานตามที่กำหนดไว้ในข้อมูลจำเพาะ แต่แล้วคำถามก็กลายเป็น "ทำไมมันถึงถูกกำหนดแบบนี้ในสเป็ค?"
Beska

สิ่งที่ดีนี้จะ (อาจ) ทำในฮาร์ดแวร์อื่นมันจะ nuke ประสิทธิภาพการทำงานกับทุกกรณีพิเศษเหล่านี้ :)
โทมัส

16

มันเป็นเพียงการประชุมเพื่อกำหนดเป็น1, หรือจะปล่อยให้มัน0 undefinedคำจำกัดความดังกล่าวธาร (0,0)เป็นการแพร่กระจายอย่างกว้างขวางเนื่องจากคำจำกัดความต่อไปนี้:

นิยามกำลังทางคณิตศาสตร์


เอกสาร ECMA-Script กล่าวถึงสิ่งต่อไปนี้เกี่ยวกับpow(x,y):

  • ถ้า y คือ +0 ผลลัพธ์คือ 1 แม้ว่า x จะเป็น NaN
  • ถ้า y คือ −0 ผลลัพธ์คือ 1 แม้ว่า x จะเป็น NaN

[ 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

อ้างอิงจาก Wikipedia:

ในการตั้งค่าส่วนใหญ่ไม่เกี่ยวข้องกับความต่อเนื่องในเลขชี้กำลังการตีความ 0 0เป็น 1 ทำให้สูตรง่ายขึ้นและไม่จำเป็นต้องมีกรณีพิเศษในทฤษฎีบท

มีหลายวิธีที่เป็นไปได้ในการปฏิบัติ0**0กับข้อดีข้อเสียสำหรับแต่ละข้อ (ดูWikipediaสำหรับการอภิปรายเพิ่มเติม)

IEEE 754-2008มาตรฐานจุดลอยแนะนำสามฟังก์ชั่นที่แตกต่างกัน

  • powถือว่า0**0เป็น1. นี่เป็นเวอร์ชันที่กำหนดไว้ที่เก่าที่สุด ถ้าเลขยกกำลังเป็นจำนวนเต็มผลลัพธ์จะเหมือนกับสำหรับpownมิฉะนั้นผลลัพธ์จะเป็นไปตามนั้นpowr(ยกเว้นกรณีพิเศษบางกรณี)
  • pownถือว่า 0 ** 0 เป็น 1 กำลังไฟฟ้าต้องเป็นจำนวนเต็มแน่นอน ค่าถูกกำหนดสำหรับฐานลบ เช่นเป็นpown(−3,5)−243
  • powrถือว่า 0 ** 0 เป็น NaN (Not-a-Number - ไม่ได้กำหนด) ค่านี้ยังเป็น NaN สำหรับกรณีเช่นpowr(−3,2)ที่ฐานน้อยกว่าศูนย์ ค่านี้กำหนดโดย exp (power '× log (base))

6

Donald Knuth

ประเภทของการยุติการอภิปรายนี้ในปี 1992 โดยมีดังต่อไปนี้:

ใส่คำอธิบายภาพที่นี่

และเดินมากยิ่งขึ้นในรายละเอียดในกระดาษของเขาสองหมายเหตุเกี่ยวกับโน้ต

โดยพื้นฐานแล้วในขณะที่เราไม่มี 1 เป็นขีด จำกัดf(x)/g(x)สำหรับทุกฟังก์ชั่นf(x)และg(x)มันยังทำให้ combinatorics ง่ายกว่ามากในการกำหนด0^0=1จากนั้นสร้างกรณีพิเศษในไม่กี่แห่งที่คุณต้องพิจารณาฟังก์ชั่นเช่น0^xซึ่ง ก็แปลกอยู่ดี หลังจากนั้นx^0มาบ่อยขึ้นมาก

การสนทนาที่ดีที่สุดที่ฉันรู้จักในหัวข้อนี้ (นอกเหนือจากเอกสาร Knuth) ได้แก่ :


หากคุณยังไม่ได้อ่านอ่านคำตอบในZero to the zero power ... ? ซึ่งเชื่อมโยงกับคำถามคุณควรมีคำตอบบางส่วนครอบคลุมแนวทางนี้ด้วย
Shafik Yaghmour

5

เมื่อคุณต้องการที่จะรู้ว่าสิ่งที่มีค่าที่คุณควรให้ไปf(a)เมื่อfไม่ได้คำนวณโดยตรงในaคุณคำนวณขีด จำกัด ของfเมื่อมีแนวโน้มที่มีต่อxa

ในกรณีที่มีx^yข้อ จำกัด ตามปกติมีแนวโน้มต่อ1เมื่อxและyมีแนวโน้มที่จะ0และโดยเฉพาะอย่างยิ่งx^xมีแนวโน้มต่อ1เมื่อมีแนวโน้มที่จะx0

ดูhttp://www.math.hmc.edu/funfacts/ffiles/10005.3-5.shtml


5

นิยามภาษา C กล่าวว่า (7.12.7.4/2):

ข้อผิดพลาดของโดเมนอาจเกิดขึ้นถ้า x เป็นศูนย์และ y เป็นศูนย์

นอกจากนี้ยังกล่าวว่า (7.12.1 / 2):

ในข้อผิดพลาดของโดเมนฟังก์ชันจะส่งคืนค่าที่กำหนดโดยการนำไปใช้ ถ้านิพจน์จำนวนเต็ม math_errhandling & MATH_ERRNO ไม่ใช่ศูนย์นิพจน์จำนวนเต็มจะไม่ได้รับค่า EDOM ถ้านิพจน์จำนวนเต็ม math_errhandling & MATH_ERREXCEPT ไม่เป็นศูนย์ข้อยกเว้นทศนิยม '' ไม่ถูกต้อง '' จะถูกเพิ่มขึ้น

โดยค่าเริ่มต้นค่าของการmath_errhandlingมีที่MATH_ERRNOเพื่อตรวจสอบสำหรับค่าerrnoEDOM


1
หวีด! ที่น่าสนใจจริงๆ! ฉันรวบรวมไฟล์ cpp โดยใช้g++ (Ubuntu/Linaro 4.8.1-10ubuntu8) 4.8.
IonicăBizău

0

ฉันต้องการไม่เห็นด้วยกับคำยืนยันของคำตอบก่อนหน้านี้ว่าเป็นเรื่องของการประชุมหรือความสะดวกสบาย (ครอบคลุมกรณีพิเศษบางประการสำหรับทฤษฎีบทต่างๆ ฯลฯ ) ที่ 0 ^ 0 ถูกกำหนดให้เป็น 1 แทนที่จะเป็น 0

การยกกำลังไม่เข้ากันได้ดีกับสัญกรณ์ทางคณิตศาสตร์อื่น ๆ ของเราดังนั้นคำจำกัดความที่เราทุกคนเรียนรู้จึงทำให้เกิดความสับสน วิธีที่แตกต่างกันเล็กน้อยในการเข้าใกล้คือการบอกว่า 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 เพราะ 'การคูณลบ' คือการหาร - เราหารด้วยสี่สองครั้ง

a ^ (1/2) คือรูท (a) เนื่องจากการคูณบางสิ่งด้วยรูทของ a เป็นครึ่งหนึ่งของงานคูณที่คูณด้วยตัวมันเองคุณจะต้องทำมันสองครั้งเพื่อคูณบางสิ่งด้วย 4 = 4 ^ 1 = (4 ^ (1/2)) ^ 2


0

เพื่อให้เข้าใจว่าคุณต้องแก้แคลคูลัส:

ใส่คำอธิบายภาพที่นี่

การขยายx^xศูนย์โดยใช้ชุดเทย์เลอร์เราได้รับ:

ใส่คำอธิบายภาพที่นี่

ดังนั้นเพื่อให้เข้าใจว่าเกิดอะไรขึ้นโดยมีขีด จำกัด เมื่อxไปที่ศูนย์เราต้องหาว่าเกิดอะไรขึ้นกับเทอมที่สองx log(x)เพราะคำศัพท์อื่น ๆ เป็นสัดส่วนกับการx log(x)ยกกำลังบางส่วน

เราจำเป็นต้องใช้การเปลี่ยนแปลง:

ใส่คำอธิบายภาพที่นี่

หลังจากการเปลี่ยนแปลงนี้เราสามารถใช้กฎของL'Hôpitalซึ่งระบุว่า:

ใส่คำอธิบายภาพที่นี่

เราจึงได้รับการเปลี่ยนแปลงที่แตกต่างออกไป:

ใส่คำอธิบายภาพที่นี่

เราจึงคำนวณได้ว่าเทอมนั้นlog(x)*xเข้าใกล้ 0 เมื่อ x เข้าใกล้ 0 มันง่ายที่จะเห็นว่าคำศัพท์อื่น ๆ ที่ต่อเนื่องเข้าใกล้ศูนย์และเร็วกว่าพจน์ที่สองด้วยซ้ำ

เมื่อถึงจุดหนึ่งx=0อนุกรมจะกลายเป็น1 + 0 + 0 + 0 + ...และจึงเท่ากับ 1


1
แม้ว่าคำตอบนี้จะน่าประทับใจ แต่ก็น่าสังเกตว่าในทางคณิตศาสตร์ขีด จำกัด ของ x-> a ของ f (x) ไม่จำเป็นต้องเท่ากับ f (a) เว้นแต่ว่าฟังก์ชันจะต่อเนื่องที่ x
jasonszhao
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.