Về cơ bản, vấn đề là phải ký kéo dài từ 32 bit để ... vô số bit, vì Python có số nguyên lớn tùy ý. Thông thường, phần mở rộng ký tự được thực hiện tự động theo hướng dẫn của CPU khi truyền, vì vậy điều thú vị là điều này khó hơn trong Python, ví dụ: C.
Bằng cách chơi xung quanh, tôi đã tìm thấy một cái gì đó tương tự như chức năng của BreizhGatch, nhưng không yêu cầu một tuyên bố có điều kiện. n & 0x80000000
trích xuất bit dấu 32 bit; sau đó, -
giữ nguyên biểu diễn 32 bit nhưng ký mở rộng nó; cuối cùng, các bit dấu mở rộng được đặt trên n
.
def toSigned32(n):
n = n & 0xffffffff
return n | (-(n & 0x80000000))
Bit Twiddling Hacks đề xuất một giải pháp khác có thể hoạt động chung hơn. n^0x80000000
lật bit bit 32 bit; sau đó - 0x80000000
sẽ đăng ký mở rộng bit đối diện. Một cách khác để suy nghĩ về nó là ban đầu, số âm là trên số dương (cách nhau bởi 0x80000000
); các ^
hoán đổi vị trí của chúng; thì -
thay đổi số âm xuống dưới 0.
def toSigned32(n):
n = n & 0xffffffff
return (n^0x80000000) - 0x80000000
Điều đó không chính xác: tất cả các tính toán phù hợp với từ của máy được thực hiện ở cấp đó. Ví dụ: ~ 1 == -2. Vì vậy, tôi đang tìm một cách để buộc kết quả vào loại int (mà không phải là những gì int() hiện, rõ ràng). –
~ 1 == -2 bằng Python trên * tất cả * hệ thống. Nếu đó không phải là trường hợp trên hệ thống bản địa, thì việc triển khai Python phải mô phỏng nó. (Xem http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy.) Lần duy nhất kích thước từ gốc có thể bị rò rỉ vào Python là khi kích thước của int lớn hơn 32 bit , có nghĩa là bạn làm cho transtion từ int đến lâu sau đó. –
Bạn không thể buộc Python chuyển đổi một giá trị dài thành int khi giá trị không khớp với một int; bạn không thể viết mã Python như thể bạn đang ở trong C.Nếu bạn muốn chuyển đổi giá trị int 32 bit không được gán 0xFFFFFFFF thành số nguyên 32 bit được bổ sung của hai ký tự đại diện bởi cùng một chuỗi bit, thì tôi đã cho bạn mã. Nếu không, tôi không chắc bạn đang cố gắng làm gì. –