二進位整數中的“1”

來源:互聯網
上載者:User

標籤:

這裡主要通過一些位元運算的技巧來找出一個整數的二進位表示中1的個數或其中某些特殊的1的位置。

 

1 的個數

求二進位表示中1的個數存在時間複雜度為O(n)(n為1的個數)的演算法。 其要點是 若整數 x 不為0, 運算式(指C語言運算式) x&(x-1) 的運算結果是將 x 的二進位表示中最右側的1消除後的值, 若x為0, 運算式的值為0。 這樣, 若 x 不為0, 我們就可以通過運算式  x = x&(x-1) 反覆消除 x 最右側的1直到x為0, 消除的次數即為所求1的個數。

C語言代碼(輸入為32位無符號整型)

1 int number_of_ones(uint32_t x) {2     int result = 0;3     while (x) {4         x = x & (x - 1);5         result++;6     }7     return result;8 }

 

最右側1的位置

最右側1的位置通過運算式 x ^ (x & (x-1))計算, 如, x: 0x12345678, x ^ (x & (x-1)) : 0x00000008

1 uint32_t right_most_one(uint32_t x) {2     return x ^ (x & (x - 1));3 }

 

最左側1的位置

求最左側1的位置相對比較複雜, 下面是一種比較直接的演算法。

1 uint32_t left_most_one(uint32_t x) {2     uint32_t test = x & (x - 1);3     while (test) {4         x = test;5         test = x & (x - 1);6     }7     return x;8 }

在Java ArrayDeque 的 allocateElements 源碼中看到一種比較有意思的演算法, 它用來計算大於一個數的2的整數次冪。 我們可以對所求2的次冪按位右移一位來求最左側1的位置。

下面給出原始碼    ps: 自行思考一下演算法的原理 :)

 1 uint32_t left_most_one2(uint32_t x) {  2     uint32_t tmp = x; 3     tmp |= (tmp >> 1); 4     tmp |= (tmp >> 2); 5     tmp |= (tmp >> 4); 6     tmp |= (tmp >> 8); 7     tmp |= (tmp >> 16); 8     tmp++; 9     return tmp ? (tmp >> 1) : (0x80000000);10 }

 

參考

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayDeque.java

二進位整數中的“1”

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.