2的非負整數次冪的判斷方法、證明以及一些思考

問題:

如何判斷一個給定的整數是否爲2的非負整數次冪?

通常的解法或者需要O(LOGN)的時間開銷;或者通過時間換空間策略,建立一個LOG(MAX)大小的hash table解決限定範圍內數據的判斷問題。我們需要意識到的是,後者事實上是把運行時的運算開銷前置到了編譯期,總的計算成本是一樣的。

前幾天在學習極客時間上吳詠煒老師的《現代C++實戰30講》課程(順便推薦吳詠煒老師的這門C++課程,需要有C++開發經驗)時,發現吳老師在範例代碼中展示了一種非常巧妙的算法:

 

X & (X - 1) == 0

 

思考了一下,發現這個算法非常優美且高效。其幾乎接近原子操作,和其他算法O(LogN)的時間開銷比起來判若雲泥。以至於我甚至一度懷疑這兩個命題的等價性。遂嘗試如下證明:

 

證明 ”X是2的非負整數次冪“ 與 ”X & (X - 1) == 0“ 是等價的;

 

充分性證明:

已知X是2的正整數次冪;可一般性假設X的二進制可表達爲m位上1,從m-1位到1位共m-1個0;任取Y < X, 可知Y的二進制表達中,第m位必爲0;顯見X & Y == 0; 可推知X & (X - 1) == 0;

 

必要性證明:

使用反證法。已知X&(X-1) == 0; 假設X不是2的正整數次冪;

則X的二進制表達爲m位上是1,從m-1位到1位至少還還存在一個1;一般性假設第n (1<= n <= m-1)(1<= n <= m-1)是1;則有:

 

X = 2^{m} + 2^{n};

 

易得:

 

X-1 = 2^m + (2^n - 1);

 

由於1 <= n <= m - 1,可得:

 

2 <= 2^n <= 2^{m-1};

 

進一步可得:

 

2 - 1 <= 2^n -1 <= 2^{m-1} - 1;

 

可推出:

 

2^m + 2 - 1 <= 2^m + 2^n -1 <= 2^m + 2^{m-1} - 1;

 

即:

 

2^m + 1 <= X - 1 <= 2^m + 2^{m-1} - 1;

 

X - 1二進制表達中第m位必定爲1;可推出X & (X - 1) != 0;與已知矛盾,假設條件不成立;

 

等價性成立。證明完畢。

 

思考:

  1. 類似的高效等價操作還有:右移操作和➗2;

  2. 針對2的整數次冪存在這樣高效的算法,可以看做是使用二進制計數的紅利。其實對於任意X進制系統中,X的任意整數次冪的判斷是同樣高效的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章