Làm thế nào tốt một lập trình viên toàn diện cần phải được với các hoạt động khôn ngoan bit? [đóng cửa]


34

Tôi đã duyệt một số mã OpenJDK gần đây và đã tìm thấy một số đoạn mã hấp dẫn ở đó có liên quan đến các hoạt động khôn ngoan . Tôi thậm chí đã hỏi một câu hỏi về nó trên StackOverflow.

Một ví dụ khác minh họa điểm:

 1141       public static int bitCount(int i) {
 1142           // HD, Figure 5-2
 1143           i = i - ((i >>> 1) & 0x55555555);
 1144           i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
 1145           i = (i + (i >>> 4)) & 0x0f0f0f0f;
 1146           i = i + (i >>> 8);
 1147           i = i + (i >>> 16);
 1148           return i & 0x3f;
 1149       }

Mã này có thể được tìm thấy trong lớp Integer .

Tôi không thể không cảm thấy ngu ngốc khi nhìn vào điều này. Tôi đã bỏ lỡ một hoặc hai lớp ở trường đại học hay đây không phải là thứ tôi phải có được ? Tôi có thể thực hiện các thao tác bit-khôn đơn giản (như ANDing, ORing, XORing, shift), nhưng thôi nào, làm thế nào mà ai đó đưa ra một mã như trên?

Làm thế nào tốt một lập trình viên toàn diện cần phải được với các hoạt động khôn ngoan bit?

Bên cạnh đó, điều khiến tôi lo lắng là người trả lời câu hỏi của tôi trên StackOverflow đã trả lời nó trong vài phút. Nếu anh ta có thể làm điều đó, tại sao tôi chỉ nhìn chằm chằm như con nai trong đèn pha?


4
Loại công việc phát triển nào bạn làm (hoặc muốn làm, nếu bạn không thực hiện ngay bây giờ)? Tôi không thấy điều này hữu ích trong việc phát triển web, nhưng tôi đã thấy rất nhiều hoạt động bitwise trong các hệ thống nhúng hoạt động.
Thomas Owens

26
Nếu tôi thuê ai đó để phát triển giao diện người dùng hoặc phát triển web, thao tác bit không phải là điều tôi muốn hỏi bởi vì, rất có thể, họ sẽ không bao giờ thấy điều đó. Tuy nhiên, tôi mong muốn ai đó làm việc với các giao thức mạng, hệ thống nhúng và trình điều khiển thiết bị hoạt động để làm quen với nó.
Thomas Owens

11
Điều gì trên trái đất là >>>một nhà điều hành?
DeadMG

10
@DeadMG: dịch chuyển phải không dấu. download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
c_maker

3
// HD, Figure 5-2sẽ là điều đầu tiên tôi nhìn vào. Theo các ý kiến ​​ở đầu tập tin, HDHenry S. Warren, Jr.'s Hacker's Delight.
schnaader

Câu trả lời:


38

Tôi muốn nói rằng là một nhà phát triển toàn diện, bạn cần hiểu các toán tử và các thao tác bitwise.

Vì vậy, ở mức tối thiểu, bạn sẽ có thể tìm ra đoạn mã trên sau một chút suy nghĩ.

Các hoạt động của bitwise có xu hướng khá thấp, vì vậy nếu bạn làm việc trên các trang web và phần mềm LOB, bạn không có khả năng sử dụng chúng nhiều.

Giống như những thứ khác, nếu bạn không sử dụng chúng nhiều, bạn sẽ không nói chuyện với họ.

Vì vậy, bạn không nên lo lắng về việc ai đó có thể tìm ra nó rất nhanh, vì họ (có thể) làm việc với loại mã này rất nhiều. Có thể viết mã hệ điều hành, mã trình điều khiển hoặc các thao tác bit khó khăn khác.


1
+1: Hoạt động theo bitwise là một chút kiến ​​thức quan trọng (không có ý định chơi chữ) cho bất kỳ nhà phát triển nào, nhưng chúng chỉ thực sự thực sự quan trọng trong các tình huống cụ thể hiện nay. Nếu bạn không bao giờ bắt gặp chúng hàng ngày thì việc có kiến ​​thức tổng quát sẽ tốt hơn là lướt qua chúng. Giữ không gian não miễn phí.
Nicholas Smith

Bạn cũng nên hiểu khi nào bạn sẽ sử dụng chúng và không né tránh việc sử dụng chúng nếu chúng là giải pháp chính xác cho vấn đề trong tay.
dùng606723

Để thêm vào nhận xét của @ user606723 - thực sự có một vài nơi thường sử dụng công cụ bitwise và thường ít gặp hơn - băm (và những thứ liên quan đến nó) và trích xuất / cài đặt màu sắc cụ thể của RGB nếu chúng được lưu trữ trong một int. Ví dụ, thông tin CPU có thể được đọc bằng cách kiểm tra các cờ bit được trả về từ một thanh ghi cụ thể, nhưng liên quan đến mã asm và thường có các hàm bao lvl cao hơn nếu cần.
TC1

36

Nếu bạn hiểu cách giải quyết các vấn đề như "xác định xem bit 3 và 8 có được đặt không", "xóa bit 5" hoặc "tìm giá trị nguyên được biểu thị bằng bit 7-12", bạn có đủ hiểu biết về toán tử bit để kiểm tra Can Hộp Twiddle Bits trong danh sách kiểm tra "tròn trịa".

Những gì trong ví dụ của bạn đến từ Hacker Delight , một bộ tổng hợp các thuật toán hiệu năng cao để xử lý các bit dữ liệu nhỏ như số nguyên. Bất cứ ai viết mã đó ban đầu sẽ không nhổ nó trong năm phút; câu chuyện đằng sau có nhiều khả năng là cần một cách nhanh chóng, không phân nhánh để đếm bit và tác giả đã dành thời gian để nhìn chằm chằm vào các chuỗi bit và nấu lên một cách để giải quyết vấn đề. Không ai sẽ hiểu làm thế nào nó hoạt động trong nháy mắt trừ khi họ đã nhìn thấy nó trước đó. Với một sự hiểu biết vững chắc về những điều cơ bản từng chút một và dành thời gian thử nghiệm mã, bạn có thể có thể tìm ra cách nó làm những gì nó làm.

Ngay cả khi bạn không hiểu các thuật toán này, chỉ cần biết chúng tồn tại sẽ làm tăng thêm "độ tròn" của bạn bởi vì khi đến lúc phải xử lý, giả sử, đếm bit hiệu suất cao, bạn sẽ biết phải học gì. Trong thế giới tiền Google, việc tìm hiểu về những điều này khó hơn rất nhiều; bây giờ nó là tổ hợp phím.

Người dùng đã trả lời câu hỏi SO của bạn có thể đã thấy vấn đề trước đó hoặc đã nghiên cứu băm. Viết cho anh ấy và hỏi.


+1 về ít nhất là nhận thức được những điều này. Đó là một điều tốt để biết một chút về rất nhiều. Nếu mọi người trong ngành bắt đầu nói về những thứ như thế này, bạn không muốn trở thành người trong phòng không có manh mối nhỏ nhất về những gì đang được thảo luận.
maple_shaft

3
+1 để giải quyết chữ viết tắt "HD" trong nhận xét mã ở trên.
Péter Török

Tôi thích loại công cụ này và chỉ cần đặt mua sách HD. Cảm ơn đã tham khảo.
tcrosley

8

Từ ví dụ của bạn, có một số điều bạn hoàn toàn nên biết mà không thực sự suy nghĩ.

1143 i = i - ((i >>> 1) & 0x55555555);

Bạn nên nhận ra mẫu bit 0x555 ... dưới dạng mẫu bit xen kẽ 0101 0101 0101 và các toán tử đang bù đắp cho nó 1 bit (bên phải) và đó là một hoạt động che giấu (và ý nghĩa của mặt nạ).

1144 i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);

Lại một mẫu, mẫu này là 0011 0011 0011. Ngoài ra, lần này nó thay đổi hai lần và che lại. sự dịch chuyển và mặt nạ theo một mô hình mà bạn sẽ nhận ra ...

1145 i = (i + (i >>> 4)) & 0x0f0f0f0f;

mô hình hóa rắn. Lần này là 00001111 00001111 và dĩ nhiên, chúng tôi sẽ chuyển nó 4 lần này. mỗi lần chúng ta thay đổi kích thước của mặt nạ.

1148 trả lại i & 0x3f;

một mẫu bit khác, 3f là một khối số không, theo sau là một khối lớn hơn.

Tất cả những điều này sẽ rõ ràng trong nháy mắt nếu bạn là "Làm tròn tốt". Ngay cả khi bạn không bao giờ nghĩ rằng mình sẽ sử dụng nó, bạn có thể sẽ bỏ lỡ một số cơ hội để đơn giản hóa rất nhiều mã của mình nếu bạn không biết điều này.

Ngay cả trong một ngôn ngữ cấp cao hơn, các bit bit được sử dụng để lưu trữ NHIỀU lượng dữ liệu lớn hơn trong các trường nhỏ hơn. Đây là lý do tại sao bạn luôn thấy các giới hạn 127/8, 63/4 và 255/6 trong các trò chơi, bởi vì bạn phải lưu trữ rất nhiều những thứ này mà không đóng gói các trường bạn sẽ buộc phải sử dụng gấp mười lần dung lượng bộ nhớ. (Chà, điều tối thượng sẽ là nếu bạn cần lưu trữ số lượng lớn booleans trong một mảng, bạn có thể tiết kiệm 32-64 lần bộ nhớ như bạn sẽ sử dụng nếu bạn không nghĩ về nó - hầu hết các ngôn ngữ đều thực hiện booleans như một từ thường sẽ là 32 bit. Những từ không cảm thấy thoải mái ở cấp độ này sẽ chống lại các cơ hội lưu trữ dữ liệu như thế này đơn giản chỉ vì họ sợ những điều chưa biết.

Họ cũng sẽ tránh xa những thứ như phân tích thủ công các gói được gửi qua mạng theo định dạng đóng gói - một thứ không quan trọng nếu bạn không sợ. Điều này có thể khiến một trò chơi yêu cầu gói 1k xuống yêu cầu 200 byte, gói nhỏ hơn sẽ lướt qua mạng hiệu quả hơn và giảm độ trễ và cho phép tốc độ tương tác cao hơn (có thể cho phép toàn bộ chế độ chơi mới cho trò chơi).


5

Tôi tình cờ nhận ra mã bởi vì tôi đã thấy nó trước đây trong phần mềm để thao tác các khung hình video. Nếu bạn thường xuyên làm việc với những thứ như CODEC âm thanh và video, giao thức mạng hoặc đăng ký chip, bạn sẽ thấy rất nhiều hoạt động theo chiều bit và nó sẽ trở thành bản chất thứ hai đối với bạn.

Bạn không nên cảm thấy tồi tệ nếu công việc của bạn xảy ra không trùng với những miền đó rất thường xuyên. Tôi biết rõ về hoạt động của bitwise, nhưng tôi chậm lại trong những dịp hiếm hoi tôi cần viết GUI, bởi vì tất cả các điều kỳ quặc với bố cục và trọng số và mở rộng và do đó tôi chắc chắn là bản chất thứ hai đối với người khác. Điểm mạnh của bạn là bất cứ nơi nào bạn có nhiều kinh nghiệm nhất.


4

những điều chính bạn cần lưu ý là cách các số nguyên được biểu diễn (nói chung là một bitvector có độ dài cố định trong đó độ dài phụ thuộc vào nền tảng) và những hoạt động nào có sẵn trên chúng

các hoạt động số học chính + - * / %có thể được hiểu mà không cần phải hiểu nó mặc dù nó có thể thuận tiện cho việc tối ưu hóa vi mô (mặc dù hầu hết thời gian trình biên dịch sẽ có thể chăm sóc điều đó cho bạn)

bộ thao tác bit | & ~ ^ << >> >>>đòi hỏi ít nhất một sự hiểu biết vượt qua để có thể sử dụng chúng

tuy nhiên, hầu hết thời gian bạn sẽ chỉ sử dụng chúng để truyền cờ bit cho một phương thức như là ORkết hợp với nhau và chuyển một int và sau đó ANDđưa ra các cài đặt dễ đọc hơn so với việc chuyển một số (tối đa 32) booleans trong danh sách tham số dài và cho phép các cờ có thể thay đổi mà không thay đổi giao diện

không đề cập đến booleans thường được giữ riêng biệt theo byte hoặc int thay vì đóng gói chúng lại với nhau như các cờ


đối với đoạn mã, nó thực hiện đếm song song các bit, điều này cho phép thuật toán chạy trong O(log(n))đó n là số bit thay vì vòng lặp ngây thơO(n)

bước đầu tiên là khó khăn nhất để hiểu nhưng nếu bạn bắt đầu từ thiết lập mà nó có để thay thế cho chuỗi các bit 0b00để 0b00, 0b01đến 0b01, 0b10đến 0b010b11để 0b10nó trở nên dễ dàng hơn để làm theo

Vì vậy, đối với bước đầu tiên i - ((i >>> 1) & 0x55555555)nếu chúng ta thực hiện ibằng 0b00_01_10_11thì đầu ra của điều này sẽ là0b00_01_01_10

(lưu ý 0x5là bằng 0b0101)

iuf chúng tôi lấy i = 0b00_01_10_11điều này có nghĩa 0b00_01_01_10 - (0b00_00_11_01 & 0b01_01_01_01)0b00_01_10_11 - 0b00_00_01_01lần lượt trở thành0b00_01_01_10

họ có thể đã làm (i & 0x55555555) + ((i >>> 1) & 0x55555555)cho cùng một kết quả nhưng đây là 1 thao tác bổ sung

các bước sau đây là trong một tĩnh mạch tương tự


4
Chất lượng quan trọng nhất của mã này là nó không có chi nhánh, có thể mang lại lợi ích thậm chí còn lớn hơn cả việc giảm độ phức tạp.
Simon Richter

3

Mọi người nên hiểu các thao tác bit-khôn ngoan cơ bản. Nó là thành phần của các hoạt động cơ bản để thực hiện các nhiệm vụ theo cách tối ưu, mạnh mẽ, cần nhiều thực hành.

Những người làm việc với thao tác bit hàng ngày (như người nhúng), tất nhiên, sẽ phát triển trực giác mạnh mẽ và một túi thủ thuật tốt đẹp.

Một lập trình viên không làm công cụ cấp thấp có bao nhiêu kỹ năng với thao tác bit-khôn ngoan? Đủ để có thể ngồi xuống với một khổ thơ như bạn dán và làm việc từ từ như thể đó là một lời trêu ghẹo não hoặc câu đố.

Tương tự như vậy, tôi muốn nói rằng một lập trình viên nhúng sẽ hiểu nhiều về http vì một nhà phát triển web hiểu về thao tác bit-khôn ngoan. Nói cách khác, không có gì phải lo lắng khi thao túng bit nếu bạn không sử dụng nó mọi lúc.


3
Trên thực tế, trong một số trường hợp, một lập trình viên nhúng phải hiểu nhiều hơn về http so với nhà phát triển web (tôi làm cả hai). Làm phát triển web, bạn thường có thể dựa vào một số loại khung. Là một nhà phát triển nhúng làm việc với các thiết bị kết nối internet, tôi đã phải viết mã ngăn xếp http từ đầu.
tcrosley

@tcrosely, vâng, bạn hoàn toàn chính xác. Có lẽ một ví dụ tốt hơn "http" sẽ là một cái gì đó như "ORM" hoặc "JEE". Điểm chính là người ta thường không thể thành thạo một số vấn đề trừ khi họ thực hành nó thường xuyên.
Angelo

Tôi đồng ý và tôi chưa bao giờ phải đối phó với ORM hoặc JEE (chỉ JME trở lại khi nó được gọi là J2ME).
tcrosley

3

Niềm vui của Hacker là một tác phẩm phái sinh. Tổ tiên của tất cả là HakMem từ năm 1972. http://w3.pppl.gov/~Hammett/work/2009/AIM-239-oc.pdf

Điều quan trọng là phải biết rằng thuật toán rõ ràng cho bất kỳ nhiệm vụ nào không nhất thiết là tốt nhất. Có rất nhiều trường hợp khi biết sự tồn tại của một giải pháp tao nhã cho một vấn đề cơ bản là điều quan trọng.


Ngoài ra còn có phiên bản HTML của HAKMEM . Nhìn vào ITEM 169
Mackie Messer

3

Làm thế nào khó là các nhà khai thác bitwise để giải thích?

Tôi lập trình các hệ thống nhúng. Tôi đã thực hành công cụ này rất nhiều. Câu hỏi được liên kết của bạn về bản đồ băm với mã

static int hash(int h) {
   // This function ensures that hashCodes that differ only by
   // constant multiples at each bit position have a bounded
   // number of collisions (approximately 8 at default load factor).
   h ^= (h >>> 20) ^ (h >>> 12);
   return h ^ (h >>> 7) ^ (h >>> 4);
}

có ý nghĩa hoàn hảo với tôi trong chừng nào sẽ mất để đọc chính tả mã. Các sự kiện được mô tả bitCountngay lập tức rõ ràng, nhưng phải mất một phút để tìm ra lý do tại sao nó thực sự đếm bit. Tuy nhiên, các bình luận sẽ rất tuyệt và sẽ giúp hiểu được những gì mã chỉ khó hơn một chút so với vấn đề băm.

Điều quan trọng là phân biệt giữa đọc và hiểu mã. Tôi có thể giải thích bitCountmã, và đọc những gì nó làm, nhưng việc chứng minh tại sao nó hoạt động hoặc thậm chí nó hoạt động sẽ mất một phút. Có một sự khác biệt giữa việc có thể đọc mã trơn tru và có thể tìm hiểu lý do tại sao mã là như vậy. Một số thuật toán đơn giản là khó. Những của hashmã có ý nghĩa, nhưng bình luận giải thích tại sao những gì đang được thực hiện. Đừng nản lòng nếu một hàm sử dụng các toán tử bitwise khó hiểu, chúng thường được sử dụng để thực hiện các công cụ toán học phức tạp, khó có thể định dạng được.

Một sự tương tự

Tôi đã quen với những thứ này. Một chủ đề mà tôi không quen là regex. Tôi thỉnh thoảng xử lý chúng trên các tập lệnh xây dựng, nhưng không bao giờ trong công việc phát triển hàng ngày.

Tôi biết cách sử dụng các yếu tố sau của regex:

  • [] lớp nhân vật
  • Các *, .+ký tự đại diện
  • Bắt đầu chuỗi ^và kết thúc chuỗi$
  • Các lớp ký tự \ d, \ w và \ s
  • Cờ / g

Điều này là đủ để tạo các truy vấn đơn giản và nhiều truy vấn tôi thấy không đi xa khỏi điều này.

Bất cứ điều gì không có trong danh sách này, tôi với tới một bảng cheat. Bất cứ điều gì, đó là, ngoại trừ {}()- Bảng cheat sẽ không đủ. Tôi biết vừa đủ về những người này để biết rằng tôi sẽ cần một bảng trắng, sách hướng dẫn tham khảo và có thể là đồng nghiệp. Bạn có thể gói một số thuật toán điên rồ vào một vài dòng regex ngắn.

Để thiết kế một regex yêu cầu hoặc gợi ý bất cứ thứ gì không có trong danh sách các yếu tố đã biết của tôi, tôi sẽ liệt kê ra tất cả các lớp đầu vào mà tôi mong đợi nhận ra và đưa chúng vào bộ kiểm tra. Tôi sẽ tạo ra regex từ từ và tăng dần, với nhiều bước không liên tục và cam kết các bước này để kiểm soát nguồn và / hoặc để chúng trong một nhận xét để tôi có thể hiểu những gì sẽ xảy ra sau đó khi nó bị hỏng. Nếu nó nằm trong mã sản xuất, tôi sẽ đảm bảo rằng nó được xem xét bởi một người có nhiều kinh nghiệm hơn.

Đây có phải là nơi bạn đang ở với các toán tử bitwise?

Vì vậy, bạn muốn được tròn trịa?

Theo ước tính của tôi, nếu bạn có thể diễn giải mã như thế này bằng cách rút ra một mảnh giấy hoặc đi đến bảng trắng và chạy qua các thao tác bằng tay, bạn đủ điều kiện làm tròn. Để đủ điều kiện trở thành một lập trình viên giỏi toàn diện trong lĩnh vực hoạt động bitwise, bạn sẽ có thể thực hiện bốn điều:

  1. Có thể đọc và viết các hoạt động chung
    một cách trôi chảy Đối với một lập trình viên ứng dụng, các hoạt động chung với các toán tử bitwise bao gồm các toán tử cơ bản |&để thiết lập và xóa các cờ. Điều này nên dễ dàng. Bạn sẽ có thể đọc và viết những thứ như

    open('file', O_WRONLY | O_APPEND | O_CREAT );
    // Use an OR operator ^ here and ^ here to set multiple flags
    

    mà không làm chậm (giả sử bạn biết những lá cờ có nghĩa là gì ).

  2. Có thể đọc các hoạt động phức tạp hơn với một số công việc
    Đếm các bit rất nhanh trong thời gian O (log (n)) mà không cần các nhánh, đảm bảo rằng số lượng va chạm trong mã băm có thể khác nhau bởi một lượng giới hạn và phân tích địa chỉ email , số điện thoại hoặc HTML với một regex là những vấn đề khó khăn. Thật hợp lý cho bất cứ ai không phải là chuyên gia trong các lĩnh vực này tiếp cận với bảng trắng, thật vô lý khi không thể bắt đầu làm việc để hiểu.

  3. Có thể viết một số thuật toán phức tạp với rất nhiều công việc
    Nếu bạn không phải là chuyên gia, bạn không nên mong đợi có thể làm những việc phức tạp và khó khăn. Tuy nhiên, một lập trình viên giỏi sẽ có thể hoàn thành nó bằng cách làm việc liên tục. Làm điều này đủ, và bạn sẽ sớm trở thành một chuyên gia :)


2

Nếu bạn đã đi đến một trường đại học đàng hoàng, bạn sẽ phải học một lớp về Toán học rời rạc. Bạn sẽ học các cổng số học và logic nhị phân, bát phân và thập lục phân.

Trên lưu ý đó là bình thường khi cảm thấy bối rối bởi điều đó, nếu đó là điều an ủi với bạn vì tôi viết các ứng dụng web chủ yếu tôi hiếm khi cần xem hoặc viết mã như thế này, nhưng vì tôi hiểu số học nhị phân và hành vi của các toán tử bitwise Cuối cùng tôi có thể tìm ra những gì đang diễn ra ở đây đủ thời gian.


2

Là một lập trình viên của điện thoại di động, tôi đã phải đối phó với điều này. Nó khá phổ biến khi thiết bị không có nhiều bộ nhớ hoặc tốc độ truyền là quan trọng. Trong cả hai trường hợp, bạn tìm cách đóng gói càng nhiều thông tin càng tốt vào một vài byte.

Tôi không nhớ việc sử dụng các toán tử bitwise trong 5 năm hoặc hơn PHP (có thể đó chỉ là tôi), không phải trong 10 năm hoặc hơn lập trình Windows, mặc dù một số công cụ Windows cấp thấp hơn có gói bit.

Bạn nói "Tôi không thể không cảm thấy ngu ngốc khi nhìn vào điều này". ĐỪNG - cảm thấy tức giận.

Bạn vừa đáp ứng đầu ra của một lập trình viên cao bồi.

Anh ta không biết gì về việc viết mã duy trì? Tôi chân thành hy vọng rằng anh ấy là người phải quay lại vấn đề này trong một năm và cố gắng ghi nhớ ý nghĩa của nó.

Tôi không biết nếu bạn cắt bình luận hoặc nếu không có bình luận nào, nhưng mã này sẽ không vượt qua đánh giá mã nơi tôi là người quản lý QA (và tôi đã vài lần).

Đây là một quy tắc tốt - "số nguyên trần" duy nhất được phép trong mã là 0 1nd 1. Tất cả các số khác phải là #defines, chi phí, enums, v.v., tùy thuộc vào ngôn ngữ của bạn.

Nếu 3 và 0x33333333 đã nói điều gì đó như NUM_WIDGET_SHIFT_BITS và WIDGET_READ_MASK thì mã sẽ dễ đọc hơn.

Xấu hổ về bất cứ ai đưa ra điều này trong một dự án nguồn mở, nhưng ngay cả đối với nhận xét mã cá nhân cũng tốt và sử dụng các định nghĩa / enum có ý nghĩa và có các tiêu chuẩn mã hóa của riêng bạn.


Tôi muốn xem xét các hằng số hex cũng được cho phép. 0xFF00là dễ đọc hơn nhiều (với tôi) hơn 0b1111111100000000. Tôi không muốn phải đếm để xác định số lượng bit đã được đặt.
Kevin Vermeer

1

Đoạn mã đặc biệt này được lấy thẳng ra khỏi cuốn sách Hacker Delight , hình 5.2. Nó trực tuyến trong C (chức năng pop) ở đây . Lưu ý hiện tại tác giả khuyên bạn nên sử dụng các phiên bản cập nhật: http://www.hackersdelight.org/HDcode/newCode/pop_arrayHS.c.txt

Nếu bạn muốn tìm hiểu các loại tối ưu hóa vi mô này, tôi sẽ đề xuất cuốn sách đó; thật thú vị, nhưng trừ khi bạn đang lập trình bit rất thấp thường thì bạn có thể sẽ không hiểu nó; và hầu hết thời gian trình biên dịch của bạn sẽ có thể thực hiện nhiều loại tối ưu hóa này cho bạn.

Nó cũng giúp viết lại tất cả các số thập lục phân trong nhị phân để hiểu các loại thuật toán này và làm việc thông qua chúng trong một hoặc hai trường hợp thử nghiệm.


1

Giải thích bằng ví dụ. Dữ liệu là chuỗi các bit. Cho phép đếm các bit trên byte 01001101 có sẵn các hoạt động sau: 1. Chúng ta có thể kiểm tra giá trị của bit cuối cùng. 2. Chúng ta có thể thay đổi trình tự.

  1. 01001101 -> byte cuối cùng là 1, tổng = 1. ca
  2. 10100110 -> byte cuối cùng là 0, tổng = 1. ca
  3. 01010011 -> byte cuối cùng là 1, tổng = 2. ca
  4. 10101001 -> byte cuối cùng là 1, tổng = 3. ca
  5. 11010100 -> byte cuối cùng là 0, tổng = 3. ca
  6. 01101010 -> byte cuối cùng là 0, tổng = 3. ca
  7. 00110101 -> byte cuối cùng là 1, tổng = 4. ca
  8. 10011010 -> byte cuối cùng là 0, tổng = 4. ca

Câu trả lời của chúng tôi: 4.

Điều này không khó, phải không? Vấn đề lớn với các hoạt động bitwise là có những điều hạn chế chúng ta có thể làm. Chúng tôi không thể truy cập một chút trực tiếp. Nhưng chúng ta có thể, ví dụ, biết giá trị của bit cuối cùng so sánh nó với MASK 00000001 và chúng ta có thể làm cho mỗi bit là giá trị cuối cùng với các hoạt động thay đổi. Tất nhiên, thuật toán kết quả sẽ trông đáng sợ đối với những người không quen sử dụng. Không có gì để làm với trí thông minh.


0

Tôi sẽ không nói bạn cần nó trừ khi công việc bạn đang làm có liên quan đến:

  • Xử lý âm thanh
  • Xử lý video
  • Đồ họa
  • Mạng (đặc biệt khi kích thước gói là quan trọng)
  • Một lượng lớn dữ liệu

Lưu trữ quyền trong cờ kiểu unix cũng là một cách sử dụng khác cho nó, nếu bạn có một mô hình quyền đặc biệt phức tạp cho hệ thống của mình hoặc thực sự muốn nhồi nhét mọi thứ vào một byte, với chi phí dễ đọc.

Ngoài những lĩnh vực đó, tôi sẽ coi đó là một điểm cộng lớn nếu nhà phát triển / nhà phát triển cao cấp có thể chứng minh sự dịch chuyển bit và sử dụng | & và ^ vì nó cho thấy sự quan tâm đến nghề nghiệp mà bạn có thể nói dẫn đến mã ổn định và đáng tin cậy hơn.

Theo như "không" nhận được phương pháp ngay từ cái nhìn đầu tiên, như đã đề cập, bạn cần một lời giải thích về những gì nó đang làm và một số nền tảng. Tôi sẽ không nói nó liên quan đến trí thông minh nhưng bạn đã quen thuộc như thế nào khi làm việc với hệ thập lục phân trên cơ sở hàng ngày và nhận ra các vấn đề mà một số mô hình nhất định có thể giải quyết.

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.