Tôi đã cố gắng học C trong thời gian rảnh rỗi và các ngôn ngữ khác (C #, Java, v.v.) có cùng một khái niệm (và thường là cùng các toán tử) …

Những gì tôi đang tự hỏi là, ở một mức độ cốt lõi, những gì không bit thay đổi ( <<, >>, >>>) làm gì, những vấn đề có thể nó giúp giải quyết, và những gì gotchas ẩn nấp xung quanh uốn cong? Nói cách khác, hướng dẫn tuyệt đối cho người mới bắt đầu để thay đổi tất cả sự tốt đẹp của nó.

operators bit-manipulation bit-shift binary-operators
chia sẻ | theo dõi
đã hỏi 19:47:15 26/09/2008
Huỳnh Minh HuyềnHuỳnh Minh Huyền
0 50 390
2

Các trường hợp chức năng hoặc không có chức năng mà bạn sẽ sử dụng bẻ khóa trong 3GL là rất ít.

– Nguyễn Tường Vân 20:19:44 26/09/2008
13

Sau khi đọc những câu trả lời này, bạn có thể muốn xem các liên kết sau: Graphics.stanford.edu/~seander/bithacks.html & jjj.de/bitwizardry/bitwizardrypage.html

– Trần Kiên Giang 15:28:13 15/06/2010
1

Điều quan trọng cần lưu ý là việc dịch chuyển bit cực kỳ dễ dàng và nhanh chóng cho máy tính. Bằng cách tìm cách sử dụng dịch chuyển bit trong chương trình của bạn, bạn có thể giảm đáng kể thời gian sử dụng bộ nhớ và thời gian thực hiện.

– Nguyễn Nhật Quân 22:56:55 23/08/2016
Hoytman: Nhưng lưu ý rằng các trình biên dịch tốt đã biết nhiều thủ thuật này và thường tốt hơn trong việc nhận ra nơi nào có ý nghĩa. – Trịnh Đình Khải 15:26:38 08/02/2019
thêm 1 bình luận  | 

7 trả lời 7

Hoạt động Cũ nhất Hữu ích
1.6k

Các toán tử dịch chuyển bit làm chính xác những gì tên của chúng ngụ ý. Họ thay đổi bit. Đây là một giới thiệu ngắn gọn (hoặc không quá ngắn gọn) cho các toán tử thay đổi khác nhau.

Người vận hành

>> là toán tử dịch chuyển phải số học (hoặc đã ký). >>> là toán tử dịch chuyển phải logic (hoặc không dấu). << là toán tử dịch chuyển trái, và đáp ứng nhu cầu của cả hai dịch chuyển logic và số học.

Tất cả những nhà khai thác có thể được áp dụng cho các giá trị số nguyên ( int, long, có thể shortvà bytehay char). Trong một số ngôn ngữ, áp dụng toán tử shift cho bất kỳ kiểu dữ liệu nào nhỏ hơn inttự động thay đổi kích thước toán hạng thành một int.

Lưu ý rằng đó <<<không phải là một toán tử, bởi vì nó sẽ là dự phòng. Cũng lưu ý rằng C và C ++ không phân biệt giữa các toán tử dịch chuyển phải.

Bạn đang xem: Bitwise là gì

Xem thêm: Enclosure Là Gì – Enclosure Trong Tiếng Tiếng Việt

Xem thêm: Route Là Gì

Họ chỉ cung cấp >>toán tử và hành vi dịch chuyển phải được triển khai được xác định cho các loại đã ký.

Ca trái (<<)

Các số nguyên được lưu trữ, trong bộ nhớ, dưới dạng một chuỗi các bit. Ví dụ: số 6 được lưu dưới dạng 32 bit intsẽ là:

00000000 00000000 00000000 00000110

Chuyển mẫu bit này sang vị trí bên trái ( 6 << 1) sẽ dẫn đến số 12:

00000000 00000000 00000000 00001100

Như bạn có thể thấy, các chữ số đã dịch chuyển sang trái theo một vị trí và chữ số cuối cùng bên phải được điền bằng 0. Bạn cũng có thể lưu ý rằng dịch chuyển sang trái tương đương với nhân với lũy thừa của 2. Vì vậy, 6 << 1tương đương với 6 * 2, và 6 << 3tương đương với 6 * 8. Một trình biên dịch tối ưu hóa tốt sẽ thay thế phép nhân bằng ca khi có thể.

Dịch chuyển không tròn

Xin lưu ý rằng đây không phải là ca tròn. Chuyển giá trị này sang trái theo một vị trí ( 3,758,096,384 << 1):

11100000 00000000 00000000 00000000

kết quả trong 3.221.225.472:

11000000 00000000 00000000 00000000

Chữ số bị dịch chuyển “khỏi cuối” bị mất. Nó không quấn quanh.

Chuyển đúng logic (>>>)

Sự dịch chuyển hợp lý bên phải là sự thay đổi đối với sự dịch chuyển trái. Thay vì di chuyển các bit sang trái, chúng chỉ đơn giản là di chuyển sang phải. Ví dụ: thay đổi số 12:

00000000 00000000 00000000 00001100

ở bên phải bởi một vị trí ( 12 >>> 1) sẽ lấy lại 6 gốc của chúng tôi:

00000000 00000000 00000000 00000110

Vì vậy, chúng ta thấy rằng dịch chuyển sang phải tương đương với sự phân chia theo quyền hạn của 2.

Mất bit đã biến mất

Tuy nhiên, một sự thay đổi không thể lấy lại các bit “bị mất”. Ví dụ: nếu chúng ta thay đổi mẫu này:

00111000 00000000 00000000 00000110

ở bên trái 4 vị trí ( 939,524,102 << 4), chúng tôi nhận được 2.147.483.744:

10000000 00000000 00000000 01100000

và sau đó dịch chuyển trở lại ( (939,524,102 << 4) >>> 4), chúng tôi nhận được 134,217,734:

00001000 00000000 00000000 00000110

Chúng tôi không thể lấy lại giá trị ban đầu của mình một khi chúng tôi đã mất bit.

Số học phải dịch chuyển (>>)

Sự dịch chuyển phải của số học hoàn toàn giống như sự dịch chuyển hợp lý, ngoại trừ thay vì đệm bằng 0, nó thay đổi với bit đáng kể nhất. Điều này là do bit có ý nghĩa nhất là bit dấu , hoặc bit phân biệt số dương và số âm. Bằng cách đệm với bit có ý nghĩa nhất, sự thay đổi bên phải của số học là bảo toàn dấu hiệu.

Ví dụ: nếu chúng ta giải thích mẫu bit này là số âm:

10000000 00000000 00000000 01100000

chúng ta có số -2,147,483,552. Chuyển vị trí này sang đúng 4 vị trí với dịch chuyển số học (-2,147,483,552 >> 4) sẽ cho chúng ta:

11111000 00000000 00000000 00000110

hoặc số -134,217,722.

Vì vậy, chúng tôi thấy rằng chúng tôi đã bảo toàn dấu của các số âm của mình bằng cách sử dụng dịch chuyển phải số học, thay vì dịch chuyển đúng logic. Và một lần nữa, chúng ta thấy rằng chúng ta đang thực hiện phân chia theo quyền hạn của 2.

Chuyên mục: Hỏi Đáp