2008-12-14 29 views
9

Đây là một theo dõi để my question yesterday:Bitwise trừ bằng Python

CMS vui lòng cung cấp ví dụ này sử dụng toán tử Bitwise để thêm hai con số trong C:

#include<stdio.h> 

int add(int x, int y) { 
    int a, b; 
    do { 
     a = x & y; 
     b = x^y; 
     x = a << 1; 
     y = b; 
    } while (a); 
    return b; 
} 

int main(void){ 
    printf("6 + 3 = %d", add(6,3)); 
    printf("6 - 3 = %d", add(6,-3)); 
    return 0; 
} 

Nó hoạt động tuyệt vời và sau đó tôi chuyển nó đến Python như sau:

def add(x, y): 
    while True: 
     a = x & y 
     b = x^y 
     x = a << 1 
     y = b 
     if a == 0: 
      break 
    return b 

print "6 + 3 = %d" % add(6,3) 
print "6 - 3 = %d" % add(6,-3) 

Cả hai đều hoạt động để bổ sung và chương trình C cũng hoạt động để trừ. Tuy nhiên, chương trình Python nhập vào một vòng lặp vô hạn cho phép trừ. Tôi đang cố gắng tìm hiểu điều này và đã đăng chương trình tại đây để thử nghiệm thêm: http://codepad.org/pb8IuLnY

Có ai có thể giải thích tại sao có sự khác biệt giữa cách xử lý C và cách xử lý CPython này?

Trả lời

2

Chuyển số âm không có giải thích phù hợp giữa trăn và C.

9

Như tôi đã chỉ ra trong phản ứng của tôi để CMS 'câu trả lời ngày hôm qua, trái chuyển một số âm là một hành vi không xác định trong C, do đó isn này' t thậm chí đảm bảo để làm việc trong C (vấn đề là làm thế nào để xử lý bit đã ký, làm bạn chuyển nó như một bit giá trị hoặc nó không bị ảnh hưởng bởi một sự thay đổi? Ủy ban tiêu chuẩn không thể đồng ý về một hành vi để nó được trái không xác định). Khi điều này xảy ra để làm việc trong C, nó dựa trên các số nguyên bit cố định để bit ngoài cùng bên trái bị đẩy ra khỏi đầu khi bạn thực hiện một ca (nó cũng yêu cầu bit dấu được coi là bit giá trị để dịch chuyển mục đích). Tất cả các kiểu số nguyên trong C là bit cố định nhưng số Python có thể lớn tùy ý. Trái chuyển một số bằng Python chỉ làm cho nó tiếp tục nhận được lớn hơn:

>>> 1 << 100 
1267650600228229401496703205376L 

Bạn có thể thử một cái gì đó như thế này:

x = (a << 1) & 0xffffffff 

Để hạn chế kết quả đến 32-bit, vấn đề là các toán tử dịch chuyển trái trong Python không dịch bit dấu của một số đã ký (là một phần của những gì được yêu cầu để làm cho giải pháp cụ thể này hoạt động). Có thể có một cách để thay đổi hành vi của toán tử shift nhưng tôi không biết làm thế nào.

+0

Cảm ơn thông tin. Điều này có nghĩa là trừ bitwise là không thể? Tất cả mọi thứ tôi đã đọc trực tuyến cho thấy biến nó thành một vấn đề bổ sung bitwise bằng cách lấy bổ sung của hai toán hạng thứ hai. – user23126

+0

Tôi nghĩ bạn cần thay đổi hành vi của toán tử dịch chuyển trái, xem câu trả lời đã chỉnh sửa của tôi. –

+0

Sự dịch chuyển trái được định nghĩa về phép nhân trong Python (http://docs.python.org/reference/expressions.html#shifting-operations) vì vậy tôi nghĩ bạn sẽ cần phải tìm cách tiếp cận khác nếu muốn điều này làm việc với các số âm . –

1

nếu i, j hai số nguyên:

Ngoài:

printf("%d",(i^j)|((i&j)<<1)); 
+0

Đừng nghĩ rằng nó hoạt động. –

0

tôi đã nhận thấy rằng bạn đang giả định rằng công trình python với những con số cùng một cách như C không.
Điều đó không hoàn toàn đúng. Có nghĩa là số int của C có chiều dài cố định là 16 bit. Để biết thông tin chi tiết về các kiểu dữ liệu C, bạn có thể tham khảo C_data_types on en.wikipedia.org
Pyhton, mặt khác, được cho là có chiều dài vô hạn cho số int.
Việc thêm các số nguyên dương có thể hoạt động theo cùng một cách. Nhưng trừ hoặc thêm số nguyên âm không phải là bản dịch ánh xạ đơn giản.
Một cách dễ hiểu đây là một ví dụ nhỏ về số âm: Hãy tưởng tượng một đại diện nguyên chiều dài cố định của 3 bit:

Unsigned

  • 000: 0
  • 001: 1
  • 010: 2
  • 011: 3
  • 100: 4
  • 101: 5
  • 110: 6
  • 111: 7

Signed:

  • 000: 0
  • 001: 1
  • .210
  • 010: 2
  • 011: 3
  • 100: -4
  • 101: -3
  • 110: -2
  • 111: -1

này hoạt động mát mẻ bởi vì bạn có thể thấy rằng 1-3=1+(-3), -3 là 101 là 5 nếu chưa được ký. Vì vậy, 1+5=6, 6: 110: -2. Điều này có nghĩa là 1-3=-2.
nó cũng trở nên lỗi khi tràn: - -4 + -1 = 3 không -5 vì nó nằm ngoài phạm vi! - 3 + 1 = -4 không phải 4 vì nó nằm ngoài phạm vi!

Như bạn có thể thấy điều này hoạt động với độ dài cố định nhưng nó không hoạt động theo cách này bằng Python.

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