關於對2取模的誤區

    2015年6月27日。

先來看個知識點,有一個數N,設MOD = N & 1,則MOD就是N % 2的結果。&就是按位與的意思,來舉個生動的例子。

    N = 3,N轉換成2進制就是11,將這個11與1按位與,將1高位不足補0,則11與01按位與,結果MOD = 1,這個MOD就是3 % 2的結果。這裏N是個奇數,當N爲偶數此處就不再舉例。
    這個N & 1有什麼用呢,顯然它可以直接得到一個數模2的結果,通過這個結果我們能夠判斷是奇數還是偶數。如果N & 1等於1,說明N是奇數,否則N是偶數。
    本文的題目叫做“關於對2取模的誤區”,那我們就言歸正傳。看代碼:
    int a = 11, b = 12;
    if(a & 1 == 1) a = 1;
    if(b & 1 == 0) b = 1;
    printf("%d %d\n", a, b);
    讀者朋友猜一猜a、b的值,a = 1? 11,b = 1, b = 12?按照上文所訴a & 1的結果肯定是1,if(a & 1 == 1)這個條件肯定是真,所以a = 1。再看看b的值b & 1的結果肯等是0,if(b & 1 == 0)這個條件肯定也是真,那麼b的值也自然等於1,好了我們去調試這個程序,發現a = 1, b = 12。額,這個結果怎麼跟我們分析的結果是不一樣的,是什麼問題呢?難道是一個數N & 1 不是取得模2的結果。其實不然,這個結論肯定是正確的,那麼問題到底出在哪裏呢?通過加括號也許我們能明白一點什麼,看下面:

   

    int a = 11, b = 12;
    if(a & 1 == 1) a = 1;
    if((b & 1) == 0) b = 1;
    printf("%d %d\n", a, b);
	

我們在(b & 1)這裏加了一個括號,然後調試程序結果跟我們分析就一致了,a = 1, b = 1。按道理說這裏加括號與否都是一樣的,其實這裏就有個很大的問題,查閱相關資料才明白,==運算符的優先級高於&運算符,第一次的代碼,if(b & 1 == 0),計算機先處理1 == 0這一部分結果是0,然後再處理b == 0這一部分,所以這個爲0即假,自然b仍然等於12。

    第二份代碼if((b & 1) == 0)這個加了括號之後,計算機就先處理b & 1,這結果是0,然後在處理0 == 0,顯然爲真,所以b就會爲1。b的問題解決了。那麼a爲什麼是正確的,上文已說過==運算符優先級是高於&運算符,if(a & 1 == 1),計算機先處理1 == 1,這個結果仍爲1,然後再處理a & 1,這個結果肯定是1即真,所以a會被賦值爲1,這個a的例子說明了什麼,意思就是“== 1”這個條件相當於沒有加,意思是有沒有這個都無所謂,結果都會是正確的。
    由此建議讀者,在這種運算符不明白的情況下,儘量加上括號,以免出現不必要的錯誤。謝謝大家聽我嘮叨這麼久。
發佈了24 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章