玩轉二進位制

2021-05-27 11:17:06 字數 1265 閱讀 8647

前段時間和朋友討論到乙個小題目:如何判斷乙個正整數是2的整數次冪。

先舉幾個例子看一看:

2^0 = 1;

2^1 = 2 = 10b;

2^2= 4 = 100b;

2^3 = 8 = 1000b;

2^4 = 16 = 10000b;

將這些整數轉換為二進位制後,就可以很明顯地看出特徵了:所有二進位制數最高位都是1。考慮正整數的二進位制機器表示,就是所有位中只有一位是1,其他位都是0。如何用簡單的辦法判斷該整數的二進位制表示中有且僅有乙個1呢?

假設該數字是v,朋友提供了乙個非常巧妙的方法:判斷v&(v-1)。如果結果是0則各個位有且僅有乙個1。將上面的結果帶入該表示式發現是準確無誤的,一位當且僅當二進位制表示為0...010...0時v-1為0...001...1,兩者相與的結果必定為0。

當然乍一看好像永遠是對的,但是這個解法還是沒有考慮特殊情況的。這裡的特殊情況就是0。當v是正數時,v-1等於111...111,這是也是滿足條件的,但是顯然,0不是2的整數次冪。所以,我們的判斷不能忘了對這個特殊情況的另外考慮。可以實現這個簡單的判斷函式如下:

int istwon(unsigned int v)

return !(v & (v - 1));

}

今天碰巧看到《程式設計之美》2.1節,這個題目也是有點意思:對於乙個位元組(8bit)的變數,求其二進位制表示中「1」的個數,要求演算法的執行效率盡可能的高。

當然最簡單的辦法是逐一地測試改位元組各個位上的數,這個題目肯定不止這麼簡單。這個方法必須經過八次測試才能得出結果,計算的次數與我們的1的個數無關係,在任何情況下都是八次。我們應該尋找計算次數更少的方法。題中給出了乙個很巧妙的解法(雖然「似曾相識」,但我並沒有想到),恰好就利用了上面那個題目的做法。

上面那個題目的v&(v-1)用在這裡,正好可以將最低位的1給「濾除」掉,這樣我們一直進行此操作知道v=0就可以根據操作的次數獲得該數字中二進位制表示1的個數。

**如下:

int count(char v)

}

這個解法的計算次數只和二進位制中1的實際個數有關,可以說是,做到了「最高效」。

題外話:

當然,我們可以尋求到o(1)的解法,與1的個數無關。方法很簡單,利用查表法,我們將0-256中每個每個數字的二進位制表示的1的個數都統計下來,存在表中,實際運算時直接到表中查詢結果。這個方法看似簡單,但是卻運用了演算法中很經典的兩個策略:「預處理」和「利用空間換時間」。在計算機儲存容量日益增大的今天,這是我們進行效能優化時需要考慮的很重要的思路之一。

二進位制 二進位制起源

現代通訊技術的基礎是二進位制編碼。早在1865年麥克斯韋總結出麥克斯韋方程組之前,美國人摩斯 morse 於1837年發明了摩斯電碼和有線電報。有線電報的出現,具有劃時代的意義 它讓人類獲得了一種全新的資訊傳遞方式,這種方式 看不見 摸不著 聽不到 完全不同於以往的信件 旗語 號角 烽火,這也是二進...

判斷二進位製半整數(二進位制)

10年後,tokitsukaze大佬已經變成了年收入超百萬的的精英程式設計師,家裡沒錢也沒礦的teitoku,找tokitsukaze大佬借1000塊錢,然後tokitsukaze大佬說,借你1024吧,湊個整數。沒錯在2進製下1024是 二進位制整數 乙個正整數滿足其值為2的k次方 k為正整數 我...

mysql二進位制 MySql二進位制連線方式詳解

使用mysql二進位制方式連線 您可以使用mysql二進位制方式進入到mysql命令提示符下來連線mysql資料庫。例項以下是從命令列中連線mysql伺服器的簡單例項 root host mysql u root p enter password 在登入成功後會出現 mysql 命令提示視窗,你可以...