Bạn đã bao giờ phải sử dụng dịch chuyển bit trong các dự án lập trình thực tế chưa? Hầu hết (nếu không phải tất cả) các ngôn ngữ cấp cao đều có toán tử shift, nhưng khi nào bạn thực sự cần sử dụng chúng?
Bạn đã bao giờ phải sử dụng dịch chuyển bit trong các dự án lập trình thực tế chưa? Hầu hết (nếu không phải tất cả) các ngôn ngữ cấp cao đều có toán tử shift, nhưng khi nào bạn thực sự cần sử dụng chúng?
Câu trả lời:
Tôi vẫn viết mã cho các hệ thống không có hỗ trợ dấu chấm động trong phần cứng. Trong các hệ thống này, bạn cần dịch chuyển bit cho gần như tất cả các số học của bạn.
Ngoài ra, bạn cần thay đổi để tạo băm. Số học đa thức (CRC, Mã Reed-Solomon là các ứng dụng chính) hoặc sử dụng dịch chuyển.
Tuy nhiên, ca dao chỉ được sử dụng vì chúng tiện dụng và thể hiện chính xác ý định của người viết. Bạn có thể mô phỏng tất cả các bit-shift với phép nhân nếu bạn muốn, nhưng điều đó sẽ khó viết hơn, khó đọc hơn và đôi khi chậm hơn.
Các trình biên dịch phát hiện các trường hợp mà phép nhân có thể được giảm bớt thành một ca dịch.
Vâng, tôi đã sử dụng chúng rất nhiều lần. Bit twiddling rất quan trọng đối với phần cứng nhúng nơi bit-mask rất phổ biến. Nó cũng quan trọng trong lập trình trò chơi, khi bạn cần từng chút hiệu suất cuối cùng.
Chỉnh sửa: Ngoài ra, tôi sử dụng chúng rất nhiều để thao tác với bitmap, ví dụ như thay đổi độ sâu màu hoặc chuyển đổi RGB <-> BGR.
Và tôi không thể nghĩ ra nhiều trường hợp khi chúng được sử dụng. Thường thì ngược lại - có một số vấn đề cụ thể và hóa ra việc sử dụng các hoạt động bit sẽ mang lại kết quả tốt nhất (thường là về mặt hiệu suất - thời gian và / hoặc không gian).
short
s trong một int
trường eger ở trạng thái Phiên trong ASP.net mà không cần phải đọc ra và khóa Phiên để đọc hai giá trị riêng biệt. Ngoài ra, chi phí bộ nhớ lưu trữ hai giá trị trong phiên cũng được lưu.
Một nơi mà tôi sử dụng chúng mọi lúc là khi chuyển các số nguyên cuối cùng cho các ứng dụng đa nền tảng. Đôi khi chúng cũng có ích (cùng với các toán tử thao tác bit khác) khi tạo đồ họa 2D.
Tôi đã sử dụng chúng một vài lần, nhưng hầu như luôn luôn để phân tích cú pháp định dạng tệp nhị phân.
Sự thay đổi bit nhanh chóng. Chúng đã được thực hiện trong các tập lệnh CPU rất lâu trước khi có các hoạt động phân chia và mô đun. Nhiều người trong chúng ta đã sử dụng dịch chuyển bit cho số học đơn giản trên bút chì và giấy, nhưng không có sẵn trên CPU của chúng tôi.
Ví dụ:
Có, nó vẫn cần thiết.
Ví dụ, trong công việc của tôi, chúng tôi phát triển phần mềm để giao tiếp với PLC thông qua cổng nối tiếp COMx. Cần phải xử lý các bit trong một byte, chúng tôi sử dụng dịch chuyển trái / phải và các toán tử logic OR, XOR, AND hàng ngày.
Ví dụ, giả sử rằng chúng ta cần bật bit 3 (từ phải sang trái) của một byte:
Nó hiệu quả hơn nhiều để làm:
Byte B;
B := B XOR 4;
Thay vì:
Byte B = 0;
String s; // 0 based index
s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);
Trân trọng.
Khi tôi viết bằng hợp ngữ, mã của tôi chứa đầy tính năng dịch chuyển bit và che dấu.
Nó cũng có một số tiền hợp lý trong C.
Chưa thực hiện nhiều bằng JavaScript hoặc ngôn ngữ máy chủ.
Có lẽ cách sử dụng hiện đại tốt nhất là đi qua một mảng đóng gói các giá trị boolean được biểu diễn dưới dạng giá trị một và số không. Tôi đã từng luôn sang trái và kiểm tra bit dấu trong hợp ngữ, nhưng trong các ngôn ngữ cấp cao hơn, bạn so sánh với một giá trị.
Ví dụ: nếu bạn có 8 bit, bạn kiểm tra bit trên cùng với "if (a> 127) {...}". Sau đó, bạn sang trái (hoặc nhân với 2), thực hiện dấu "và" với 127 (hoặc thực hiện phép trừ 256 nếu bit cuối cùng được đặt) và thực hiện lại.
Tôi đã sử dụng chúng rất nhiều trong nén / giải nén hình ảnh, nơi các bit trong một ảnh bitmap được nén. Sử dụng http://en.wikipedia.org/wiki/Huffman_coding , những thứ đang được nén bao gồm nhiều số lượng bit khác nhau (chúng không phải tất cả đều được căn chỉnh theo byte) và do đó bạn cần phải dịch chuyển bit khi mã hóa hoặc giải mã chúng .
Dịch chuyển bit không giải quyết được các vấn đề lập trình cấp cao, mà chỉ là đôi khi chúng ta phải giải quyết các vấn đề cấp thấp hơn, và thật tiện lợi khi không phải viết một thư viện riêng trong C để làm điều đó. Đó là khi nó được sử dụng nhiều nhất là tôi đoán.
Cá nhân tôi đã sử dụng nó trong việc viết bộ mã hóa cho bộ chuyển đổi bộ ký tự EBCDIC .
Vâng tôi có. Như bạn có thể nghi ngờ, nó rất có thể được tìm thấy trong chương trình cấp thấp, ví dụ như phát triển trình điều khiển của thiết bị. Nhưng, tôi đã làm việc trong một dự án C #, nơi tôi phải phát triển một dịch vụ web nhận dữ liệu từ các thiết bị y tế. Tất cả dữ liệu nhị phân mà thiết bị lưu trữ được mã hóa thành các gói SOAP, nhưng dữ liệu nhị phân đã được nén và mã hóa. Vì vậy, để giải nén nó, bạn sẽ phải thực hiện rất nhiều thao tác bit. Và hơn nữa, bạn sẽ phải thực hiện nhiều chuyển đổi bit để phân tích cú pháp bất kỳ thông tin hữu ích nào, ví dụ số sê-ri thiết bị là nửa dưới của byte thứ hai hoặc tương tự như vậy. Ngoài ra, tôi đã thấy một số người trong thế giới .NET (C #) sử dụng Bit masking và Flag Attribute, cá nhân tôi chưa bao giờ muốn làm điều đó.
Khi chuyển đổi số từ endian nhỏ sang định dạng endian lớn và ngược lại
Tôi làm việc cho một nhà sản xuất thiết bị ngoại vi máy tính. Tôi đã gặp phải và phải triển khai mã sử dụng dịch chuyển bit, khá nhiều mỗi ngày.
Dịch chuyển bit được sử dụng rất nhiều trong việc giải mã các giao thức của trò chơi trực tuyến. Các giao thức được thiết kế để sử dụng càng ít băng thông càng tốt, vì vậy thay vì truyền số lượng người chơi trên một máy chủ, tên, v.v. trong int32s, tất cả thông tin được đóng gói thành càng ít byte càng tốt. Ngày nay, nó không thực sự cần thiết với hầu hết mọi người sử dụng băng thông rộng, nhưng khi chúng được thiết kế ban đầu, mọi người sử dụng modem 56k để chơi game, vì vậy mỗi bit đều được tính.
Ví dụ nổi bật nhất về điều này là trong các trò chơi nhiều người chơi của Valve, đặc biệt là Counter-Strike, Counter-Strike Source. Giao thức Quake3 cũng giống như vậy, tuy nhiên Unreal không hoàn toàn giống như giao thức mỏng.
Đây là một ví dụ (.NET 1.1)
string data = Encoding.Default.GetString(receive);
if ( data != "" )
{
// If first byte is 254 then we have multiple packets
if ( (byte) data[0] == 254 )
{
// High order contains count, low order index
packetCount = ((byte) data[8]) & 15; // indexed from 0
packetIndex = ((byte) data[8]) >> 4;
packetCount -= 1;
packets[packetIndex] = data.Remove(0,9);
}
else
{
packets[0] = data;
}
}
Tất nhiên bạn xem đây là một dự án thực sự hay chỉ là một sở thích (trong C #) là tùy thuộc vào bạn.
Biến đổi Fourier nhanh - FFT và đó là kỹ thuật Cooley-Tukey sẽ yêu cầu sử dụng các hoạt động dịch chuyển bit.
Tôi đã phải viết một chương trình để phân tích cú pháp các tệp .ifo trên đĩa DVD. Đây là những tập tin giải thích có bao nhiêu tiêu đề, chương, menu, v.v. trên đĩa. Chúng được tạo thành từ các bit đóng gói với mọi kích thước và sự liên kết. Tôi nghi ngờ nhiều định dạng nhị phân yêu cầu dịch chuyển bit tương tự.
Tôi đã thấy các toán tử bitwise được sử dụng khi nhiều cờ được sử dụng làm tham số thuộc tính. Ví dụ số 4 = 1 0 0 có nghĩa là một trong ba cờ được đặt. Điều này không tốt cho API công khai nhưng nó có thể tăng tốc mọi thứ trong các trường hợp đặc biệt vì việc kiểm tra các bit rất nhanh.
Mọi bitblt-er mà tôi từng viết không thể hoàn thành với khả năng trượt các bit sang trái và phải.
Tôi sử dụng nó trong một dự án cho một hệ thống nhúng phải đọc dữ liệu EDID của màn hình. Một số dữ liệu trong EDID được mã hóa như sau:
Byte # 3:
Chần ngang - 8 bit dưới
Byte # 4:
Nibble dưới: Chần ngang - 4 bit
trên Upper Nibble: cái gì đó khác
Có, khi thực hiện giao tiếp nhị phân giữa các ứng dụng Java và C #, một là thứ tự byte big-endian và thứ còn lại là little-endian (không nhất thiết phải theo thứ tự này). Tôi đã tạo một lớp InputStream có thể đọc các số với một thứ tự byte khác và nó sử dụng tính năng chuyển byte để hoạt động.
Đôi khi bạn muốn đặt 4 quần short trong 4 byte dài, nó sẽ là trường hợp sử dụng dịch chuyển byte. Tôi nghĩ tôi đã làm điều đó nhiều năm trước ...
Một điều rất phổ biến khác là thực hiện dịch chuyển 4 bit khi trích xuất nibble cao của một byte, tức là
#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F)
#define LOW_NIBBLE(byte) ( (byte) & 0x0F)
Có, dịch chuyển bit luôn được sử dụng trong phần mềm nhúng cấp thấp. Nó cũng có thể được sử dụng như một trò ảo thuật để thực hiện các phép toán cực nhanh, hãy xem
http://betterexplained.com/articles/undilities-quakes-fast-inverse-square-root/
Có, mọi lúc. Giống như các macro này để đóng gói và giải nén một tọa độ 3 không gian thành / từ một số nguyên 32 bit:
#define Top_Code(a, b, c) ((((a) + x) << 20) | (((b) + y) << 10) | ((c) + z))
#define From_Top_Code(a, b, c, f) (a = (((f) >>> 20) - x), b = ((((f) & 0xffc00) >>> 10) - y), c = (((f) & 0x3ff) - z))
Tôi đã từng (nhiều, nhiều năm trước) đã viết một quy trình xuất cho một dự án tạo Bảng tính Excel bằng cách sử dụng cấu trúc Excel Oper. Đây là một định dạng tệp nhị phân yêu cầu một lượng lớn bit xoay. Liên kết sau đây cung cấp một hương vị của Safari Books cấu trúc Oper .