Tại sao các toán tử bitwise có mức độ ưu tiên thấp hơn so với so sánh?


63

Ai đó có thể giải thích lý do, tại sao trong một loạt các ngôn ngữ phổ biến nhất (xem ghi chú bên dưới) các toán tử so sánh (== ,! =, <,>, <=,> =) Có mức độ ưu tiên cao hơn các toán tử bitwise (&, |, ^, ^ , ~)?

Tôi không nghĩ rằng tôi đã từng gặp phải việc sử dụng trong đó quyền ưu tiên này là tự nhiên. Nó luôn luôn là những thứ như:

  if( (x & MASK) == CORRECT ) ...   // Chosen bits are in correct setting, rest unimportant

  if( (x ^ x_prev) == SET )      // only, and exactly SET bit changed

  if( (x & REQUIRED) < REQUIRED )   // Not all conditions satisfied

Các trường hợp tôi sử dụng:

  flags = ( x == 6 | 2 );     // set bit 0 when x is 6, bit 1 always.

gần như không có.

Động lực của các nhà thiết kế ngôn ngữ để quyết định ưu tiên như vậy của các nhà khai thác là gì?


Ví dụ: tất cả ngoại trừ SQL ở 12 ngôn ngữ hàng đầu đều giống như trong danh sách phổ biến ngôn ngữ lập trình tại langpop.com: C, Java, C ++, PHP, JavaScript, Python, C #, Perl, SQL, Ruby, Shell, Visual Basic.


16
lỗi trong thiết kế ban đầu trở lại trong C
ratchet freak

7
@gnat, điểm của khiếu nại đó là gì? OP đã không nói "tất cả", chỉ là "một loạt các ngôn ngữ phổ biến nhất". Và đại đa số theo thứ tự này. Trong bảng này, chỉ một trong số 12 (SQL) hàng đầu không có: langpop.com

3
@ dan1111 điểm, một cách tự nhiên, để giúp người trả lời hiểu rõ hơn câu hỏi được hỏi và cung cấp câu trả lời tốt hơn. Bạn thấy đấy, đây không phải là nơi dành cho Trò chơi đoán - hay, như trang tham quan nói, "Đây không phải là một diễn đàn thảo luận. Không có trò chuyện."
gnat

7
@gnat, tôi đồng ý với mối quan tâm của bạn về trò chơi đoán, nhưng tôi không nghĩ điều này đủ điều kiện khi gần như mọi ngôn ngữ phổ biến thể hiện hành vi được mô tả.

5
@Dunk: Cách tiếp cận "bằng linh cảm" phổ biến là [arithmetics] [logic operator] [arithmetics]. Hầu hết các lập trình viên không tạo ra một mớ hỗn độn các dấu ngoặc đơn như thế if(((x+getLowX()) < getMinX) || ((x-getHighX())>getMaxX())))- hầu hết sẽ cho rằng các ưu tiên của arithologists trên logic và viết if( ( x + getLowX() < getMinX ) || ( x - getHighX() > getMaxX() )) giả định ưu tiên +ở trên <. Bây giờ theo trực giác if( x ^ getMask() != PATTERN ) nên hành xử giống nhau, XOR là toán tử số học. Thực tế nó được hiểu if( x ^ ( getMask() != PATTERN ) )là hoàn toàn phản trực giác.
SF.

Câu trả lời:


72

Các ngôn ngữ đã sao chép từ C và đối với C, Dennis Ritchie giải thích rằng ban đầu, trong B (và có lẽ là đầu C), chỉ có một hình thức &tùy thuộc vào bối cảnh đã làm theo chiều bit và logic. Sau đó, mỗi hàm có toán tử của nó: &cho bitwise và &&cho logic. Rồi anh tiếp tục.

Giới thiệu chậm trễ của họ giải thích sự không phổ biến của các quy tắc ưu tiên của C. Trong B một người viết

if (a == b & c) ...

để kiểm tra xem có abằng bckhông khác không; trong một biểu thức có điều kiện như vậy tốt hơn là &có độ ưu tiên thấp hơn ==. Khi chuyển đổi từ B sang C, người ta muốn thay thế &bằng &&một tuyên bố như vậy; để làm cho việc chuyển đổi ít đau đớn hơn, chúng tôi đã quyết định giữ quyền ưu tiên của &toán tử tương tự ==và chỉ phân chia mức độ ưu tiên của &&một chút &. Ngày nay, dường như tốt hơn là nên di chuyển các ưu tiên tương đối của &==, và do đó đơn giản hóa một thành ngữ C phổ biến: để kiểm tra giá trị bị che giấu so với giá trị khác, người ta phải viết

if ((a & mask) == b) ...

trong đó các dấu ngoặc đơn bên trong là bắt buộc nhưng dễ bị lãng quên.


1
Điều đó sẽ không thất bại nếu c=2Hay có a==bkết quả ~0và không 1?
SF.

Có vẻ như vậy, a == b trả về 0 hoặc 1, xem cm.bell-labs.com/cm/cs/who/dmr/kbman.html .
AProgrammer

Kiểm tra tài liệu tham khảo trong câu trả lời và đọc văn bản trước.
SShaheen

1
@MasonWheeler: Đặc biệt là trong các hệ thống nhúng, đôi khi cần sử dụng các macro giống như chức năng [trong một số trường hợp, chúng có thể cung cấp hiệu suất tốt hơn so với các chức năng nội tuyến và trong một số hệ thống nhúng có thể rất quan trọng]. Khai báo biến trong các macro như vậy là không thể; sử dụng một biến toàn cục trong một macro có thể hoạt động, nhưng dường như thực sự khó khăn.
supercat

6
@MasonWheeler: Bạn có thể tìm thấy Raspberry Pi hoặc Arduino với giá $ 0,5 với số lượng 1000 không?
supercat

7

Các toán tử bitwise có liên quan đến các toán tử logic cả về mặt khái niệm và ngoại hình, điều này có thể giải thích tại sao chúng ở gần nhau trong bảng ưu tiên. Có lẽ người ta thậm chí có thể lập luận rằng nó sẽ gây nhầm lẫn &khi cao hơn ==, nhưng &&sau đó đã thấp hơn ==.

Khi một tiền lệ ưu tiên (!) Được thiết lập, có lẽ tốt hơn cho các ngôn ngữ khác tuân theo nó để đảm bảo tính nhất quán.

Tuy nhiên, tôi có xu hướng đồng ý với bạn rằng điều này không tối ưu. Trong sử dụng thực tế, các toán tử bit giống như các toán tử toán học hơn các toán tử logic và sẽ tốt hơn nếu chúng được nhóm với các toán tử toán học trước.

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.