Bạn đã bao giờ phải sử dụng dịch chuyển bit trong các dự án thực tế chưa?


83

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:


58

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.


37

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.


Biệt phái. Tôi thực hiện rất nhiều công việc lập trình nhúng và dịch chuyển bit là một thao tác phổ biến.
e.James

Chuyển đổi RGB <-> BGR tại đây.
Neil N

25
  • Tạo các giá trị cờ đẹp cho enums (thay vì nhập thủ công 1, 2, 4 ...)
  • Giải nén dữ liệu từ các trường bit (nhiều giao thức mạng sử dụng chúng)
  • Đường cong Z đi ngang
  • Hack hiệu suất

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).


Bạn có thể cần nó để lưu trữ ví dụ hai shorts trong một inttrườ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.
David d C e Freitas

15

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.


Thứ hai, viết một bộ chuyển đổi cho bộ ký tự EBCDIC. Thật không may, điều này thực sự đang thực hiện công việc cấp thấp bằng ngôn ngữ cấp cao, nhưng nó là cần thiết trong một số trường hợp.
Michael Meadows

9

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.


7

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ụ:

  • Tôi đã sử dụng sự thay đổi bit cho các dự án liên quan đến việc tính các vật liệu tổng hợp lớn vào các yếu tố chính của chúng.
  • Tôi cũng đã sử dụng dịch chuyển bit để tìm căn bậc hai và khối lập phương của các số nguyên lớn tùy ý.

bạn có thể vui lòng đăng một ví dụ về cách bạn sử dụng nó để tìm khối lập phương hoặc căn bậc hai? Tôi hơi không hiểu làm thế nào điều này có thể được thực hiện.
Xsmael

5

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.


1
Bạn có thể muốn thêm lý do tại sao 4 liên quan đến bit 3 (từ phải sang trái)
HCP

1
Tại sao s [5]? Nó không phải là S [2]?
IamIC

1
B: = B XOR 4; Trong trường hợp này, để bật bit cụ thể, không nên chỉ HOẶC? XOR không được sử dụng để chuyển đổi? stackoverflow.com/questions/47981/…
Hari

4

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.


3

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 .


3

Ví dụ, trong việc thực hiện các phương pháp mật mã trên các ngôn ngữ như C, C ++. Tệp nhị phân, thuật toán nén và hoạt động danh sách logic - hoạt động theo bitwise luôn tốt =)


3

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 .


3

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 đó.


3

Vâng. Tôi phải viết các thuật toán mã hóa trước và điều đó chắc chắn sử dụng chúng.

Chúng cũng hữu ích khi sử dụng số nguyên, v.v. để theo dõi các trạng thái.



3

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.


3

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.


2

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.


Thực hiện các quy trình FFT của riêng bạn? tut-tut :) Tôi thừa nhận rằng tôi cũng đã tự mình làm điều đó - thật tuyệt vì đã hiểu sâu về thuật toán.
Marty

2

Tìm lũy thừa gần nhất của hai số lớn hơn hoặc bằng số đã cho:

1 << (int)(ceil(log2(given)))

Cần thiết để tạo họa tiết trên phần cứng không hỗ trợ kích thước họa tiết tùy ý.


1

Có, đã sử dụng chúng trong trình phân tích cú pháp luồng truyền tải MPEG2-2. Nó dễ dàng hơn và dễ đọc hơn.


1

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ự.


1

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.


1

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.


1

Tôi đã sử dụng chúng trong các trò chơi để đóng gói nhiều cờ thành một byte / char để lưu vào thẻ dữ liệu. Những thứ như lưu trữ trạng thái của các thiết bị mở khóa, v.v. Ngày nay không còn quá nhiều yêu cầu nhưng có thể tiết kiệm công việc.


1

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

1

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 ...


1

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 biệt đúng nếu bạn đang làm việc trực tiếp với phần cứng, lấy dữ liệu trực tiếp từ các thanh ghi với các ánh xạ bit tùy ý.
Chris

0

Dịch chuyển bit cũng được yêu cầu khi giao tiếp với thiết bị "cấp thấp hơn", hộp ethernet-IO kỹ thuật số eq hoặc PLC, thường đóng gói các giá trị đầu vào / đầu ra không yêu cầu thành byte.



0

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))        

0

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 .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.