Tại sao Math.pow (0, 0) === 1?


84

Chúng ta đều biết rằng 0 0 là vô định.

Nhưng , javascript nói rằng:

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

C ++ nói điều tương tự:

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

TẠI SAO?

Tôi biết điều đó:

>Math.pow(0.001, 0.001)
0.9931160484209338

Nhưng tại sao Math.pow(0, 0)ném không có lỗi? Hoặc có thể là một NaNsẽ tốt hơn 1.


3
@zzzzBov: Theo định nghĩa tiêu chuẩn, "a <sup> b </sup> = exp (b ln (a))", nó không được xác định. Cố gắng xác định nó là "giới hạn <sub> x-> 0 </sub> f (x) <sup> g (x) </sup>" trong đó "f" và "g" đều có giới hạn bằng 0 đưa ra giá trị không xác định giá trị, vì nó phụ thuộc vào sự lựa chọn chức năng của bạn. (Xin lỗi vì ký hiệu bị lệch; tôi không thể tìm ra cách lấy ký hiệu trên trong nhận xét).
Mike Seymour

@MikeSeymour, vâng, tôi biết rằng 0⁰ (sử dụng các ký tự unicode) là không xác định theo định nghĩa đó, tuy nhiên, nếu bạn đọc nhận xét của tôi, bạn nên lưu ý rằng phần trích dẫn tham chiếu đến "thế giới toán học" chứ không phải bất kỳ "định nghĩa tiêu chuẩn" nào. Đó là sự khác biệt mà tôi đã đề cập ban đầu và câu hỏi đã được cập nhật để sửa sắc thái này.
zzzzBov

2
@AJMansfield Ừm ... a ^ 0 = 1 cho khác 0 a.
Beska

Nó cho phép các chức năng phụ thuộc vào các sản phẩm của xác suất để mang lại kết quả hợp lý. Đó là một quan niệm không đúng khi cho rằng máy tính là bộ xử lý toán học tượng trưng. Ngôn ngữ C có một triển khai cụ thể trong thế giới thực trong khi thế giới toán học của bạn có thể quá lý tưởng để được đưa vào silicon.
IRTFM

26
Đối với phiên bản toán học của câu hỏi này - "tại sao chúng ta thường định nghĩa 0 ^ 0 = 1?" - math.stackexchange có rất nhiều câu trả lời hay: math.stackexchange.com/questions/11150/…
PLL

Câu trả lời:


78

Trong C ++ Kết quả của pow (0, 0) kết quả là về cơ bản thực hiện hành vi được xác định kể từ toán học chúng ta có một tình huống mâu thuẫn nơi N^0nên luôn luôn có 1nhưng 0^Nnên luôn luôn 0cho N > 0, vì vậy bạn sẽ không có kỳ vọng toán học như là kết quả của việc này một trong hai. Bài đăng trên diễn đàn Wolfram Alpha này đi vào chi tiết hơn một chút.

Mặc dù pow(0,0)kết quả 1là hữu ích cho nhiều ứng dụng như Cơ sở lý luận cho Tiêu chuẩn Quốc tế — Ngôn ngữ Lập trình — C nêu trong phần bao gồm hỗ trợ số học dấu phẩy động IEC 60559 :

Nói chung, C99 tránh kết quả NaN trong đó giá trị số là hữu ích. [...] Kết quả của pow (∞, 0) và pow (0,0) đều là 1, vì có những ứng dụng có thể khai thác định nghĩa này. Ví dụ: nếu x (p) và y (p) là bất kỳ hàm giải tích nào trở thành 0 tại p = a, thì pow (x, y), bằng exp (y * log (x)), tiếp cận 1 khi p tiếp cận a.

Cập nhật C ++

Như leemes chỉ ra một cách chính xác tôi ban đầu liên quan đến tài liệu tham khảo cho phức tạp phiên bản của pow trong khi không phức tạp tuyên bố phiên bản đó là lỗi miền các tiêu chuẩn dự thảo C ++ rơi trở lại với tiêu chuẩn dự thảo C và cả C99C11 trong phần 7.12.7.4 Các chức năng pow đoạn 2 nói ( nhấn mạnh của tôi ):

[...] Lỗi miền có thể xảy ra nếu x bằng 0 và y bằng không. [...]

mà theo như tôi có thể nói có nghĩa là hành vi này là hành vi không xác định Xoay lại một chút phần 7.12.1 Xử lý điều kiện lỗi cho biết:

[...] lỗi miền xảy ra nếu đối số đầu vào nằm ngoài miền mà hàm toán học được xác định. [...] Đối với lỗi miền, hàm trả về một giá trị do triển khai xác định; nếu biểu thức số nguyên math_errhandling & MATH_ERRNO khác không, biểu thức số nguyên errno nhận giá trị EDOM; [...]

Vì vậy, nếu có lỗi miền thì đây sẽ là hành vi được xác định thực thi nhưng trong cả hai phiên bản mới nhất của gccclanggiá trị của errno0do đó nó không phải là lỗi miền cho các trình biên dịch đó.

Cập nhật Javascript

Đối với Javascript , Đặc tả ngôn ngữ ECMAScript® trong phần 15.8 Đối tượng toán học dưới 15.8.2.13 pow (x, y) cho biết trong số các điều kiện khác:

Nếu y là +0, kết quả là 1, ngay cả khi x là NaN.


1
@leemes Mình cho rằng trang đó sai, tiêu chuẩn không nói nên trả lại NaN. Giá trị trả về được xác định bởi triển khai. cplusplus.com mà bạn khẳng định không phải là một nguồn đáng tin cậy thực sự chính xác hơn ở đây.
giữa các

@interjay Tôi đoán ý bạn là câu trả lời đã bị xóa; Tôi chỉ trích dẫn về tính không đáng tin cậy của nó, hy vọng nó có thể giải thích cho sự phản đối (không phải do tôi). Cả hai trang đều là wiki, vì vậy độ tin cậy của chúng phụ thuộc vào những người biên tập là con người và mắc lỗi. ;)
leemes


@ShafikYaghmour Tôi đã liên kết câu hỏi tương tự (trong câu trả lời đã xóa).
leemes

1
@Alek Tôi đánh giá cao phản hồi, tôi cố gắng viết câu trả lời mà tôi muốn đọc từ những người khác. Không phải lúc nào tôi cũng thành công nhưng tôi cố gắng. Viết những câu hỏi hay thậm chí còn khó hơn, tôi chỉ cố gắng làm điều đó một lần và tôi đã dành nhiều thời gian hơn cho nó, sau đó tôi làm câu trả lời của mình.
Shafik Yaghmour

35

Trong JavaScript Math.powđược định nghĩa như sau :

  • Nếu y là NaN, kết quả là NaN.
  • Nếu y là +0, kết quả là 1, ngay cả khi x là NaN.
  • Nếu y là −0, kết quả là 1, ngay cả khi x là NaN.
  • Nếu x là NaN và y là khác không thì kết quả là NaN.
  • Nếu abs (x)> 1 và y là + ∞, kết quả là + ∞.
  • Nếu abs (x)> 1 và y là −∞, kết quả là +0.
  • Nếu abs (x) == 1 và y là + ∞, kết quả là NaN.
  • Nếu abs (x) == 1 và y là −∞, kết quả là NaN.
  • Nếu abs (x) <1 và y là + ∞, kết quả là +0.
  • Nếu abs (x) <1 và y là −∞, kết quả là + ∞.
  • Nếu x là + ∞ và y> 0, kết quả là + ∞.
  • Nếu x là + ∞ và y <0, kết quả là +0.
  • Nếu x là −∞ và y> 0 và y là một số nguyên lẻ thì kết quả là −∞.
  • Nếu x là −∞ và y> 0 và y không phải là số nguyên lẻ thì kết quả là + ∞.
  • Nếu x là −∞ và y <0 và y là một số nguyên lẻ thì kết quả là −0.
  • Nếu x là −∞ và y <0 và y không phải là số nguyên lẻ thì kết quả là +0.
  • Nếu x là +0 và y> 0, kết quả là +0.
  • Nếu x là +0 và y <0, kết quả là + ∞.
  • Nếu x là −0 và y> 0 và y là một số nguyên lẻ thì kết quả là −0.
  • Nếu x là −0 và y> 0 và y không phải là số nguyên lẻ thì kết quả là +0.
  • Nếu x là −0 và y <0 và y là một số nguyên lẻ thì kết quả là −∞.
  • Nếu x là −0 và y <0 và y không phải là số nguyên lẻ thì kết quả là + ∞.
  • Nếu x <0 và x là hữu hạn và y là hữu hạn và y không phải là số nguyên thì kết quả là NaN.

nhấn mạnh của tôi

như một quy tắc chung, các hàm bản địa của bất kỳ ngôn ngữ nào phải hoạt động như được mô tả trong đặc tả ngôn ngữ. Đôi khi điều này bao gồm "hành vi không xác định" một cách rõ ràng trong đó người triển khai phải xác định kết quả sẽ như thế nào, tuy nhiên đây không phải là trường hợp của hành vi không xác định.


Phụ lục F trong tiêu chuẩn C99 và C11 có cùng đặc điểm kỹ thuật này. Một triển khai phải xác định __STDC_IEC_559__để thông báo rằng nó phù hợp với đặc điểm kỹ thuật này. Phụ lục F mô tả số học dấu phẩy động IEC 60559. Tôi tin rằng một thông số kỹ thuật C được phép phù hợp một phần với Phụ lục F (ví dụ: pow (0, 0) == 1) và không được định nghĩa __STDC_IEC_559__.
Howard Hinnant

@HowardHinnant hmmm, có vẻ như trong trường hợp gccclang đoạn thông tin đó có thể không hoàn toàn hữu ích, điều đó thật không khuyến khích.
Shafik Yaghmour

6
Tôi không biết rằng câu trả lời này có ích. Tất nhiên, chức năng sẽ hoạt động như được định nghĩa trong thông số kỹ thuật. Nhưng sau đó câu hỏi chỉ trở thành "Tại sao nó được định nghĩa theo cách này trong thông số kỹ thuật?"
Beska

Điều tốt này (có lẽ) thực hiện trong phần cứng, ngược lại nó sẽ nuke hiệu suất với tất cả những trường hợp đặc biệt :)
Thomas

16

Nó chỉ là quy ước để xác định nó là 1, 0hoặc để lại nó undefined. Định nghĩa pow (0,0)này được phổ biến rộng rãi vì định nghĩa sau:

định nghĩa sức mạnh toán học


Tài liệu ECMA-Script cho biết những điều sau về pow(x,y):

  • Nếu y là +0, kết quả là 1, ngay cả khi x là NaN.
  • Nếu y là −0, kết quả là 1, ngay cả khi x là NaN.

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


3
math.stackexchange có rất nhiều cuộc thảo luận và giải thích tốt cho định nghĩa 0 ^ 0 = 1: math.stackexchange.com/questions/11150/…
PLL

14

Theo Wikipedia:

Trong hầu hết các cài đặt không liên quan đến tính liên tục trong số mũ, việc diễn giải 0 0 thành 1 đơn giản hóa các công thức và loại bỏ sự cần thiết của các trường hợp đặc biệt trong các định lý.

Có một số cách có thể để điều trị 0**0với ưu và nhược điểm của mỗi cách (xem Wikipedia để biết thêm một cuộc thảo luận).

Tiêu chuẩn dấu chấm động IEEE 754-2008 đề xuất ba chức năng khác nhau:

  • powcoi 0**0như 1. Đây là phiên bản được định nghĩa lâu đời nhất. Nếu lũy thừa là một số nguyên chính xác thì kết quả giống với for pown, nếu không thì kết quả là for powr(trừ một số trường hợp ngoại lệ).
  • powncoi 0 ** 0 là 1. lũy thừa phải là một số nguyên chính xác. Giá trị được xác định cho các cơ sở âm; ví dụ, pown(−3,5)−243.
  • powrcoi 0 ** 0 là NaN (Not-a-Number - không xác định). Giá trị cũng là NaN cho các trường hợp như powr(−3,2)cơ sở nhỏ hơn 0. Giá trị được xác định bởi exp (power '× log (base)).

6

Donald Knuth

đã giải quyết cuộc tranh luận này vào năm 1992 với những điều sau đây:

nhập mô tả hình ảnh ở đây

Và thậm chí còn đi sâu hơn vào chi tiết trong bài báo của ông Hai ghi chú về ký hiệu .

Về cơ bản, trong khi chúng tôi không có 1 là giới hạn của f(x)/g(x)cho tất cả không phải tất cả các chức năng f(x)g(x), nó vẫn làm cho tổ hợp nên đơn giản hơn nhiều để xác định 0^0=1, và sau đó chỉ cần làm cho trường hợp đặc biệt trong số ít những nơi mà bạn cần phải xem xét các chức năng như 0^x, mà dù sao cũng kỳ lạ. Rốt cuộc x^0xuất hiện thường xuyên hơn rất nhiều.

Một số cuộc thảo luận hay nhất mà tôi biết về chủ đề này (ngoài bài báo Knuth) là:


Nếu bạn chưa đọc một số hãy đọc các câu trả lời trong Zero to the zero power ...? được liên kết với câu hỏi mà bạn nên một số câu trả lời cũng bao gồm cách tiếp cận này.
Shafik Yaghmour

5

Khi bạn muốn biết bạn nên cung cấp giá trị f(a)nào khi fkhông thể tính toán trực tiếp a, bạn sẽ tính toán giới hạn của fthời điểm xcó xu hướng hướng tới a.

Trong trường hợp của x^y, các giới hạn thông thường có xu hướng hướng tới 1khi nào xycó xu hướng 0, và đặc biệt là x^xhướng đến 1khi xcó xu hướng 0.

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


5

Định nghĩa ngôn ngữ C cho biết (7.12.7.4/2):

Lỗi miền có thể xảy ra nếu x bằng 0 và y bằng 0.

Nó cũng nói (7.12.1 / 2):

Trên một lỗi miền, hàm trả về một giá trị do triển khai xác định; nếu biểu thức số nguyên math_errhandling & MATH_ERRNO khác không, biểu thức số nguyên errno nhận giá trị EDOM; nếu biểu thức số nguyên math_errhandling & MATH_ERREXCEPT khác không, ngoại lệ dấu phẩy động '' không hợp lệ '' sẽ được đưa ra.

Theo mặc định, giá trị của math_errhandlingMATH_ERRNO, vì vậy hãy kiểm tra errnogiá trị EDOM.


1
Rất tiếc! Điều đó thực sự thú vị! Tôi biên soạn tập tin cpp của tôi sử dụngg++ (Ubuntu/Linaro 4.8.1-10ubuntu8) 4.8.
Ionica Bizău

0

Tôi không đồng ý với khẳng định của một số câu trả lời trước đó rằng vấn đề quy ước hoặc thuận tiện (bao gồm một số trường hợp đặc biệt cho các định lý khác nhau, v.v.) mà 0 ^ 0 được định nghĩa là 1 thay vì 0.

Phép lũy thừa không thực sự phù hợp với các ký hiệu toán học khác của chúng ta, vì vậy định nghĩa mà chúng ta học được để lại chỗ cho sự nhầm lẫn. Một cách tiếp cận hơi khác là nói rằng a ^ b (hoặc exp (a, b), nếu bạn muốn) trả về giá trị một cách nhân đôi tương đương với việc nhân một số thứ khác với a, được lặp lại b lần.

Khi chúng ta nhân 5 với 4, 2 lần, chúng ta được 80. Chúng ta đã nhân 5 với 16. Vậy 4 ^ 2 = 16.

Khi bạn nhân 14 với 0, 0 lần, chúng ta còn lại với 14. Chúng ta đã nhân với 1. Do đó, 0 ^ 0 = 1.

Dòng suy nghĩ này cũng có thể giúp làm rõ số mũ âm và phân số. 4 ^ (- 2) là số 16, vì 'phép nhân âm' là phép chia - chúng ta chia cho bốn hai lần.

a ^ (1/2) là căn (a), bởi vì nhân một thứ với căn của a là một nửa công việc nhân giống như nhân nó với chính nó - bạn sẽ phải thực hiện nó hai lần để nhân một thứ với 4 = 4 ^ 1 = (4 ^ (1/2)) ^ 2


0

Để hiểu điều này, bạn cần giải toán:

nhập mô tả hình ảnh ở đây

Mở rộng x^xkhoảng 0 bằng chuỗi Taylor, chúng ta nhận được:

nhập mô tả hình ảnh ở đây

Vì vậy, để hiểu điều gì đang xảy ra với giới hạn khi xvề 0, chúng ta cần tìm hiểu điều gì đang xảy ra với số hạng thứ hai x log(x), bởi vì các số hạng khác tỷ lệ thuận với việc x log(x)nâng lên thành một số lũy thừa.

Chúng ta cần sử dụng phép chuyển đổi:

nhập mô tả hình ảnh ở đây

Bây giờ sau khi chuyển đổi này, chúng ta có thể sử dụng quy tắc L'Hôpital, quy tắc này nói rằng:

nhập mô tả hình ảnh ở đây

Vì vậy, phân biệt sự chuyển đổi đó chúng ta nhận được:

nhập mô tả hình ảnh ở đây

Vì vậy, chúng tôi đã tính toán rằng số hạng log(x)*xtiếp cận 0 khi x tiếp cận 0. Thật dễ dàng thấy rằng các số hạng liên tiếp khác cũng tiến tới số 0 và thậm chí nhanh hơn số hạng thứ hai.

Vì vậy, tại thời điểm x=0, chuỗi trở thành 1 + 0 + 0 + 0 + ...và do đó bằng 1.


Mặc dù câu trả lời này rất ấn tượng, nhưng cần lưu ý rằng trong toán học, giới hạn x-> a của f (x) không nhất thiết phải bằng f (a), trừ khi hàm liên tục tại x.
jasonszhao
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.