不使用迴圈,求二進位制中1的個數

2021-09-27 12:44:54 字數 1583 閱讀 9978

(設x , y,z 代表二進位制中一位位元位的值)

已知 i (x1 x2),j = (0 x1)。 則 i-j 所對應的的十進位制數就是 i  中1的個數。ij

i - j

0000

0001

0001

1001

0111

0110

那麼對於乙個 int 型別 32位的數,我們以2位元位為塊進行劃分 i  。對應的 i 和 j 如下。

i  = (x1 x2   x3 x4   x5 x6  ...   x31 x32)b

j  = (0 x1     0 x3     0 x5   ...     0 x31) b  。j = (i  >> 1) & 0x5555 5555;(0x5555 5555 = 0101 0101 0101....0101 b)

n = i - j = (y1 y2    y3 y4    y5 y6 ... y31 y32 )b;此時 n 中 每2位元位對應 i 中每2位位元位 1 的個數。

2位元塊合併為4位元塊:m = (n & 0x3333 3333) + ((n >> 2) & 0x3333 3333);( 0x3333 3333 = 0011 0011 0011...0011b)

(2位元最大表示十進位制為2,相加最大為4,溢位位為3位)

00  y3 y4     00 y7 y8 ... 00 y31 y32

+   00  y1 y2    00  y5 y6 ... 00 y29 y30

————————————————————

4位元塊合併為8位元塊:k = n + (n >> 4)) & 0x0f0f 0f0f;

(同理,4位元位相加最大表示8,溢位位為4位)

(0x 0f0f 0f0f = 0000 1111 0000 1111 ...1111 b)

0   0   0  0     z5 z6 z7 z8 ...    0      0     0    0       z29 z30 z31 z32

+  z1 z2 z3 z4     0   0   0   0  ...  z25 z26 z27 z28         0    0     0     0

————————————————————————————————

所有8位元塊合併到乙個8位元塊:p = k * 0x01010101;(* 0x0101 0101= (k << 24) + (k << 16) + (k << 8) + k)

(8位元位相加最大表示16,溢位位為5位)

最後將前8位位元位就是該數2進製中1的個數:num_of_1 = p >> 24;

int num_of_1(int n)

/*迴圈*/

int num_of_1(int n)

return count;

}

求二進位制中1的個數

在 程式設計之美 一書中有一節提到如何求乙個位元組的無符號整型變數二進位制表示中中1的個數,主要提到了四種方法。下面簡單介紹一下 1.求餘法 在將十進位制數轉換為二進位制數時,採用除2取餘法。將每次除2得到的餘數儲存起來逆序輸出便是該十進位制整數的二進位制表示。因此可以採用這種方法去統計1的個數。i...

求二進位制中1的個數

解法有很多種 以乙個位元組無符號位元組變數作為例子 解法一 求餘法 在將十進位制數轉換為二進位制數時,採用除2取餘法。將每次除2得到的餘數儲存起來逆序輸出便是該十進位制整數的二進位制表示。因此可以採用這種方法去統計1的個數。public int count byte n return sum 解法二...

求二進位制中1的個數

這是乙個經常會在筆試和面試中遇到的題目,今天我做到了這個題目,就來分享一下我對這個題目的解決思路。首先拿到這個題目,我們的基本思路是 先判斷最後一位是否為1,接著把數字依次右移,判斷每一位是否為1,直到整數變為0為止。基於這個思路我們可以寫下如下的 int count int n n n 1 ret...