問題來源,今天早上和一捨友吃早餐的時候談到的一個問題,將一個整數按照二進制逆序,然後輸出逆序後的數值。
我們知道數值在內存中都是以二進制的形式存放的,假如我們是32位機,每8位為一個字節,int型在32位機上是占4個字節,即32位。
如 2 = 0000 0000 0000 0000 0000 0000 00000 0010(32位)
逆 ^2 = 0100 0000 0000 0000 0000 0000 00000 0000 (這裡用^表示逆轉)
那麼這個操作要如何執行呢?首先補充幾點知識:
1)a = a << 1 ,表示將a左移一位,如:0010->0100 (一般後面是補0的)
2)b = b >> 1 ,表示將b右移一位,如:0100->0010 (一般前面是補0的)
3)b & 1 ,這個表示按位與操作,比如:2 & 1,其實執行的是如下操作:
0000 0000 0000 0000 0000 0000 00000 0010 = 2
0000 0000 0000 0000 0000 0000 00000 0001 = 1
0000 0000 0000 0000 0000 0000 00000 0000 = 2 & 1 = 0
這個操作,將前31位全部置為0,只保留最後一位不變,效果就是取出最後一位的值。
4)a &= ~1 ,相比這個不需要解釋了吧?同3)一樣,但是~表示將0的位置,置為1;1的位置,置為0。
5)a |= 1 ,這個表示按位或操作(a = a | 1),比如:2 | 1,其實是執行如下操作:
0000 0000 0000 0000 0000 0000 00000 0010 = 2
0000 0000 0000 0000 0000 0000 00000 0001 = 1
0000 0000 0000 0000 0000 0000 00000 0011 = 2 | 1 = 3
好了,下面看一下如下代碼.....
當前環境:win7_32bit,vs2010,c++
復制代碼
1 #include <stdio.h>
2
3 int main(void)
4 {
5 int i = 32,a = 2; //32位 0000 0000 0000 0000 0000 0000 0000 0010 = 2
6 int b = a; //另存一份
7
8 while (i--)
9 {
10 a = a << 1;
11 a &= ~1; //~1 = 1111 1111 1111 1111 1111 1111 1111 1110 確保第31位上為0
12 if (b & 1) // 1 = 0000 0000 0000 0000 0000 0000 0000 0001
13 {
14 a |= 1; //確保第31位上為1
15 }
16 b = b >> 1;
17 }
18
19 printf("%d\n",a);
20
21 return 0;
22 }
復制代碼
思想:總體思想就是:
1)首先使a,b的值相等;
2)然後,每次從b尾部取出一位(從第32位一直取到第0位,用i循環控制);注意:b = b >> 1,b一直在右移,以確保每次取出其最後一位。
3)最後,將其追加在a的末尾。注意:a = a << 1,a一直在左移,以確保循環32次之後,末尾第一個追加的數字,抵達第一位。
-------------------------------------------------------------------------------------------------------