2009-06-01 32 views
9

Tôi chỉ cắn kịch bản sau đây:Tại sao "**" ràng buộc chặt chẽ hơn phủ định?

>>> -1 ** 2 
-1 

Bây giờ, đào bới trong các tài liệu Python, it's clear that this is intended behavior, nhưng tại sao? Tôi không làm việc với bất kỳ ngôn ngữ nào khác có sức mạnh như một toán tử nội trang, nhưng không có liên kết phủ định đơn nhất chặt chẽ nhất có thể có vẻ nguy hiểm phản trực giác với tôi.

Có lý do nào được thực hiện theo cách này không? Các ngôn ngữ khác với các nhà khai thác điện có hoạt động tương tự không?

+1

http://www.wolframalpha.com/input/?i = -1^2 sản lượng -1 Nó giống nhau trong Mathematica –

+4

Đó là lý do tại sao tôi không thích ký hiệu infix. (expt -1 2) là rõ ràng, như là (- (expt 1 2)). – Svante

+0

Nó chắc chắn phản trực giác: không nếu dấu trừ là giữa hai toán hạng, nhưng là một toán hạng đơn nhất, nó sẽ được ưu tiên (nhưng nó không bao giờ làm, chỉ là một trong những điều kỳ lạ). –

Trả lời

22

Hành vi đó cũng giống như trong công thức toán học, vì vậy tôi không chắc chắn vấn đề là gì hoặc tại sao nó phản trực giác. Bạn có thể giải thích nơi bạn đã thấy một cái gì đó khác nhau? "**" luôn ràng buộc nhiều hơn "-": -x^2 không giống như (-x)^2

Chỉ cần sử dụng (-1) ** 2, chính xác như bạn làm trong môn toán.

+0

@nosklo - Cá nhân tôi không đồng ý. Tôi thường sẽ giải thích -x^2 như là (-x)^2 * trừ khi * bạn đang trừ. Vì vậy, 1-x^2 sẽ là 1 + - (x^2) –

+6

@ Jason: đi đọc cuốn sách tiền đại số của bạn một lần nữa ... đó không phải là cách toán học hoạt động. – rmeador

+7

@ Jason, bạn có thể không đồng ý nhưng đó là tiêu chuẩn mà các nhà toán học đã giải quyết. –

3

Nếu tôi phải đoán, đó là vì có toán tử lũy thừa cho phép các lập trình viên dễ dàng nâng số lên các lũy thừa phân đoạn. Các số âm được nâng lên các lũy thừa phân đoạn kết thúc với một thành phần tưởng tượng (thường), do đó có thể tránh được bằng cách liên kết ** chặt chẽ hơn so với đơn nhất -. Hầu hết các ngôn ngữ không thích số ảo. Cuối cùng, tất nhiên, nó chỉ là một quy ước - và để làm cho mã của bạn có thể đọc được bởi chính bạn và những người khác xuống dòng, có thể bạn sẽ muốn nhóm rõ ràng (-1) của bạn để không ai khác bị bắt bởi cùng một cái bẫy :) Chúc may mắn!

4

Câu trả lời ngắn gọn: đó là cách ưu tiên tiêu chuẩn hoạt động trong môn toán.

Hãy nói rằng tôi muốn đánh giá 3x đa thức 3x 2 + 5.

def polynomial(x): 
    return 3*x**3 - x**2 + 5 

Có vẻ tốt hơn so với ...

def polynomial 
    return 3*x**3 - (x**2) + 5 

Và cách thứ nhất là đường đi các nhà toán học làm điều đó. Các ngôn ngữ khác với lũy thừa làm việc theo cùng một cách. Lưu ý rằng toán tử phủ định cũng liên kết nhiều hơn lỏng lẻo so với phép nhân, do đó,

-x*y === -(x*y) 

Đó cũng là cách chúng thực hiện trong toán học.

+1

Ví dụ phép trừ nhị phân có vẻ không liên quan. Ví dụ trừ đơn nhất với phép nhân có giá trị hơn. –

+0

- (x * y) trên thực tế giống như (-x) * y, vì vậy việc phủ định liên kết nhiều hay ít lỏng lẻo hơn phép nhân không thực sự rõ ràng với điều này (mặc dù tôi đồng ý với bạn). Ngoài ra, @ S.Lott, tôi không chắc chắn toán học phân biệt giữa unary và nhị phân -... – weronika

+0

@weronika: Chúng có thể giống nhau về mặt toán học, nhưng chúng không nhất thiết giống nhau trong một chương trình máy tính. Ví dụ, nếu bạn đang làm việc với các số nguyên 32 bit, thì '(-0x40000000) * 2' không giống với' - (0x40000000 * 2) ', bởi vì nguyên nhân thứ hai gây ra tràn. Nếu môi trường của bạn bẫy tràn, thì chỉ cái đầu tiên là chính xác. Điều này cũng có thể áp dụng cho Python nếu bạn đang thao tác các số nguyên 32 bit, ví dụ: thông qua numpy. –

-1

Ocaml không làm như vậy

# -12.0**2.0 
    ;; 
- : float = 144. 

Đó là loại kỳ lạ ...

# -12.0**0.5;; 
- : float = nan 

Nhìn vào liên kết mặc dù ... order of operations

+2

Ocaml bị hỏng. Nó không tuân theo quy tắc toán học cơ bản này. – nosklo

1

Dường như trực quan để tôi.

Nắm tay, bởi vì nó phù hợp với ký hiệu toán học: -2^2 = -4.

Thứ hai, toán tử ** được FORTRAN giới thiệu rộng rãi từ lâu. Trong FORTRAN, -2 ** 2 cũng là -4.

Các vấn đề liên quan