題意
輸入乙個整數,輸出該數32位二進位制表示中1的個數。其中負數用補碼表示。
思路做這個題目時,發現自己對計算機中補碼反碼原碼的理解不夠深入,這裡再複習一下:
在計算機中,所有的數值都是以其補碼表示的,因為用補碼可以將兩個數的劍法轉化為加法,方便加法器工作。
對於正數,其原始碼、補碼、反碼都是一致的(除此之外還有移碼,就是將補碼的符號位取反),一般以最高位作為符號位,正數的符號位為0,負數為1,則例如32位(4位元組)的有符號整型數,第一位是符號位,低位的31位是數值位,以補碼表示的話,最大的正整數為(2^31 - 1),即符號位為0,其餘為1(0111…1111)
對於負數,符號位為1,其反碼為原碼除符號位外全部取反, 補碼為反碼+1,則表示-(2^31 - 1)的補碼應為(111…1111),但實際上還可以再減1,即將(1000…0000)表示-231。所以32位最小整數字-231。
對於0,有正0負0:
[+0]原碼=0000 0000, [-0]原碼=1000 0000
[+0]反碼=0000 0000, [-0]反碼=1111 1111
[+0]補碼=0000 0000, [-0]補碼=0000 0000
會發現其實0只有一種補碼,那是因為補碼加1進製將符號位捨棄,溢位後直接取0000 0000,這也是為了保證加法器可以算減法。
還有乙個知識:負數的補碼等於其相反數的補碼減一再逐位取反,例如四位表示的7,其補碼位0111,則-7的補碼位1001,驗證:將兩個數的補碼相加(0111)+(1001) = (0000)最高位溢位得到結果0,符合運算規則。
回到題目,則可以知道,若輸入的資料是整數,則可以直接不斷右移,判斷最後一位是否為1,其實就是看對2取模是否為1,若輸入的是負數,則先對其取反再減一,則得到的這個正數其實將其所有位取反就得到原來負數的補碼,可以先計算這個正數的1的個數,再用總位數減去該值,就是負數補碼中1的個數。
**
class solution
int count = 0;
while(n)
if(flag)
count = 32 - count; //若n原來是負數,則其補碼中的1恰好和轉換後的正數的1互補
return count;
}};
劍指Offer 11 二進位制中1的個數
思路 如果乙個整數不為0,那麼這個整數至少有一位是1。如果我們把這個整數減1,那麼原來處在整數最右邊的1就會變為0,原來在1後面的所有的0都會變成1 如果最右邊的1後面還有0的話 其餘所有位將不會受到影響。舉個例子 乙個二進位制數1100,從右邊數起第三位是處於最右邊的乙個1。減去1後,第三位變成0...
劍指offer 11 二進位制中1的個數
輸入乙個整數,輸出該數二進位制表示中1的個數。其中負數用補碼表示。用1 1自身左移運算,其實後來就不是1了 和n的每位進行位與,來判斷1的個數 public class solution11 flag flag 1 return count public static void main strin...
《劍指Offer》11 二進位制中1的個數
題目 11.二進位制中1的個數 知識點 位運算 題目描述 輸入乙個整數,輸出該數二進位制表示中1的個數。其中負數用補碼表示。解題思路 解法一 這是我當時自己的思路,即通過除二取餘法來求輸入的十進位制數字的二進位制的每一位,再判斷其是否為一,當輸入數字為負數的時候,取其補碼 原數字取反加一 我使用的取...