2010-10-02 48 views
49

Tôi bối rối như khi tôi nên sử dụng một Boolean vs nhà khai thác Bitwisetoán tử Boolean vs nhà khai thác Bitwise

and vs &, or vs | 

Ai đó có thể soi sáng cho tôi để khi nào tôi sử dụng mỗi khi sẽ sử dụng một trong khác ảnh hưởng đến tôi các kết quả?

+13

Lưu ý rằng các câu trả lời bạn sẽ áp dụng gần như tất cả các ngôn ngữ khác (chủ đạo). – delnan

Trả lời

45

Dưới đây là một vài hướng dẫn:

  • toán tử Boolean thường được sử dụng trên giá trị boolean nhưng các nhà khai thác Bitwise thường được sử dụng trên nguyên giá trị.
  • Các toán tử Boolean là ngắn mạch nhưng các toán tử bitwise là không ngắn mạch.

Các đoản mạch hành vi rất hữu ích trong các biểu thức như thế này:

if x is not None and x.foo == 42: 
    # ... 

này sẽ không hoạt động chính xác với các nhà điều hành Bitwise & vì cả hai bên sẽ luôn luôn được đánh giá, đưa ra AttributeError: 'NoneType' object has no attribute 'foo'. Khi bạn sử dụng toán tử boolean and, biểu thức thứ hai không được đánh giá khi biểu thức đầu tiên là Sai. Tương tự, or không đánh giá đối số thứ hai nếu giá trị đầu tiên là True.

+8

Bổ sung: Trong Python '&', '|', '^' cũng được thiết lập hoạt động. – kennytm

+2

Bổ sung bổ sung: trong Python, bit-khôn ngoan sẽ không cho phép các loại hỗn hợp, nhưng boolean sẽ. ví dụ. 'True hoặc" True "' là tốt (nó sẽ trả về giá trị trung thực đầu tiên), nhưng 'True | "True" 'sẽ ném một ngoại lệ. – Hannele

+4

@Hannele Không liên quan gì đến các loại hỗn hợp. Các hoạt động bitwise chỉ có ý nghĩa với các số nguyên và bất kỳ loại nào khác sẽ ném một ngoại lệ. Điểm ở đây là Python xử lý False và True là 0 và 1 tương ứng: '0 == False' và' 1 == True' đều đúng. –

1

Thao tác Boolean là các phép toán logic.

Thao tác bit hoạt động trên các bit nhị phân.

hoạt động

Bitwise:

>>> k = 1 
>>> z = 3 
>>> k & z 
1 
>>> k | z 
3 

Các hoạt động:

And & 1 if both bits are 1, 0 otherwise 
Or | 1 if either bit is 1 
Xor^1 if the bits are different, 0 if they're the same 
Not ~ Flip each bit 

Một số trong những ứng dụng của các hoạt động Bitwise:

1) Thiết lập và Clearing Bits

Boolean hoạt động:

>>> k = True 
>>> z = False 
>>> k & z # and 
False 
>>> k | z # or 
True 
>>> 
+0

Đối với các hoạt động boolean, bạn không có nghĩa là "và" và "hoặc" thay vì "&" và "|"? –

+0

Có .. Có .. Cảm ơn, tôi có ý đó. – pyfunc

2

Các gợi ý là trong tên:

  • toán tử Boolean là để thực hiện phép toán logic (thật thử nghiệm chung trong lập trình và logic hình thức)
  • nhà khai thác Bitwise là dành cho "bit-twiddling" (thao tác ở mức độ thấp của các bit theo kiểu dữ liệu byte và số)

Mặc dù có thể và thực sự đôi khi được mong muốn (điển hình ly vì lý do hiệu quả) để thực hiện các phép toán logic với các toán tử bitwise, bạn nên tránh chúng vì mục đích như vậy để ngăn chặn các lỗi tinh vi và các tác dụng phụ không mong muốn.

Nếu bạn cần thao tác bit, thì các toán tử bitwise được xây dựng theo mục đích.Cuốn sách thú vị: Hackers Delight chứa một số ví dụ thú vị và thực sự hữu ích về những gì có thể đạt được với bit-twiddling.

17

Về lý thuyết, andor đi thẳng từ logic boolean (và do đó hoạt động trên hai boolean để sản xuất một boolean), trong khi &| áp dụng boolean và/hoặc các bit riêng lẻ của số nguyên. Có rất nhiều câu hỏi ở đây về cách làm việc sau này chính xác.

Dưới đây là chênh lệch thực tế có khả năng ảnh hưởng đến kết quả của bạn:

  1. andor ngắn mạch, tức là True or sys.exit(1) sẽ không thoát khỏi, bởi vì đối với một giá trị nhất định (True or ..., False and ...) của toán hạng đầu tiên, thứ hai người ta sẽ không thay đổi kết quả = không cần phải được đánh giá. Nhưng |& không ngắn mạch - True | sys.exit(1) sẽ ném bạn ra khỏi REPL.
  2. (Chỉ áp dụng cho một số ngôn ngữ có quá tải toán tử, bao gồm Python :) &| là các toán tử thông thường và có thể bị quá tải - andor được giả mạo thành ngôn ngữ (mặc dù ít nhất là bằng Python, phương pháp đặc biệt để ép buộc boolean có thể có tác dụng phụ).
  3. (chỉ áp dụng cho một vài ngôn ngữ [xem nhận xét của KennyTM] :) andor trả lại (luôn luôn không bao giờ thực sự hiểu điều này, cũng như tôi không cần) giá trị của toán hạng thay vì True hoặc False. Điều này không thay đổi ý nghĩa của các biểu thức boolean trong điều kiện - 1 or True1, nhưng 1 cũng đúng. Nhưng nó đã từng được sử dụng để mô phỏng toán tử có điều kiện (cond ? true_val : false_val trong cú pháp C, true_val if cond else false_val bằng Python từ một vài năm). Đối với &|, loại kết quả phụ thuộc vào cách toán hạng quá tải các phương pháp đặc biệt tương ứng (True & FalseFalse, 99 & 73, cho các tập hợp công đoàn/giao lộ ...).

Nhưng ngay cả khi ví dụ: a_boolean & another_boolean sẽ hoạt động giống hệt nhau, giải pháp phù hợp đang sử dụng and - chỉ đơn giản là vì andor được kết hợp với biểu thức và điều kiện boolean trong khi &| đứng cho bit twiddling.

+0

Điểm # 3 cũng áp dụng cho Ruby, Perl và Javascript. Nó không phải là Python cụ thể. – kennytm

11

Đây là một sự khác biệt hơn nữa, trong đó có tôi bối rối trong một thời gian chỉ là bây giờ: vì & (và các nhà khai thác Bitwise khác) có độ ưu tiên cao hơn and (và các toán tử logic khác) các khái niệm sau đánh giá các giá trị khác nhau:

0 < 1 & 0 < 2 

so

0 < 1 and 0 < 2 

để wit, sản lượng đầu tiên False vì nó là tương đương với 0 < (1 & 0) < 2, do đó 0 < 0 < 2, do đó 012.359..

3

Nếu bạn đang cố gắng thực hiện các thao tác boolean theo nguyên tắc trong numpy, câu trả lời hơi khác. Bạn có thể sử dụng &| cho các hoạt động boolean khôn ngoan, nhưng andor sẽ trả về lỗi giá trị.

Để an toàn, bạn có thể sử dụng numpy logic functions.

np.array([True, False, True]) | np.array([True, False, False]) 
# array([ True, False, True], dtype=bool) 

np.array([True, False, True]) or np.array([True, False, False]) 
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

np.logical_or(np.array([True, False, True]), np.array([True, False, False])) 
# array([ True, False, True], dtype=bool) 
0

Boolean 'và' vs '&' Bitwise:

Pseudo-code/Python đã giúp tôi hiểu sự khác biệt giữa các:

def boolAnd(A, B): 
    # boolean 'and' returns either A or B 
    if A == False: 
     return A 
    else: 
     return B 

def bitwiseAnd(A , B): 
    # binary representation (e.g. 9 is '1001', 1 is '0001', etc.) 

    binA = binary(A) 
    binB = binary(B) 



    # perform boolean 'and' on each pair of binaries in (A, B) 
    # then return the result: 
    # equivalent to: return ''.join([x*y for (x,y) in zip(binA, binB)]) 

    # assuming binA and binB are the same length 
    result = [] 
    for i in range(len(binA)): 
     compar = boolAnd(binA[i], binB[i]) 
     result.append(compar) 

    # we want to return a string of 1s and 0s, not a list 

    return ''.join(result) 
Các vấn đề liên quan