首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

判斷整數是否為 2 的 N 次方:位運算技巧與數學證明

     編輯:關於C語言

在程式設計中,判斷一個正整數 x 是否為 2 的冪次方(即 2n)是一個經典問題。最優雅且高效的解法莫過於位運算表達式:x & (x - 1) == 0。若結果為真,則 x 是 2 的冪次方;否則不是。這個技巧廣泛應用於演算法優化、記憶體對齊檢查等場景。

核心邏輯:二進制特徵

一個正整數是 2 的冪次方,當且僅當其二進制表示中有且僅有一個 1,其餘皆為 0。例如:

  • 1 (20) → 1
  • 2 (21) → 10
  • 4 (22) → 100
  • 8 (23) → 1000

反之,若非 2 的冪次方,其二進制中至少包含兩個 1。

為何 x & (x - 1) 能判斷?

x - 1 運算會將 x 二進制中最右邊的 1 變為 0,並將該 1 右側的所有 0 變為 1。例如:

  • x = 8 (1000),x - 1 = 7 (0111)
  • x = 12 (1100),x - 1 = 11 (1011)

若 x 僅有一個 1(即 2 的冪次方),則 x & (x - 1) 的所有位都為 0,結果為 0。若 x 有多個 1,則最高位的 1 仍保留在結果中,結果非 0。

嚴格數學證明(雙向證明)

許多教程只證明「2 的冪次方滿足條件」,卻忽略了逆命題。以下補充完整證明:

定義

  • 設正整數 X 的二進制為 x₁x₂...xₙ(x₁=1,n>0)。
  • X 是 2 的冪次方 ⇔ 二進制中有且僅有一個 1(即 x₁=1,x₂=...=xₙ=0)。
  • X 不是 2 的冪次方 ⇔ 存在 j (1 使 xⱼ=1。

證明 1:若 X 是 2 的冪次方,則 X & (X-1) = 0

  • X = 1 時:1 & 0 = 0,成立。
  • X > 1 時:X = 100...0(n-1 個 0),X-1 = 11...1(n-1 個 1)。按位與運算結果全為 0。

證明 2:若 X 不是 2 的冪次方,則 X & (X-1) ≠ 0

分兩種情況討論:

  1. X 為奇數:最低位為 1。X-1 將最低位變 0,高位不變。按位與運算保留高位的 1,結果非 0。
  2. X 為偶數:最低位為 0,且高位至少有兩個 1。設最右邊的 1 位於第 j 位。X-1 將該 1 變 0,右側 0 變 1。按位與運算中,第 j 位變 0,但更高位的 1 保留,結果非 0。

程式碼實現(C/C++)

bool isPowerOfTwo(int x) {
    return x > 0 && (x & (x - 1)) == 0;
}

注意:必須檢查 x > 0,因為 0 和負數不符合定義,且 0 & -1 = 0 會誤判。

應用場景與擴展

  • 記憶體對齊檢查:分配器常要求大小為 2 的冪次方。
  • 環形緩衝區索引:利用 & (size-1) 替代取模運算,前提是 size 為 2 的冪次方。
  • 位圖操作:快速判斷標誌位是否唯一。

這個技巧展示了位運算在演算法設計中的威力:以 O(1) 時間、無分支指令完成判斷,是系統級程式設計的必備技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved