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

Java 位運算符深度解析:補碼、移位、邏輯運算與實戰技巧

     編輯:Java 相關知識

前言:位運算是底層優化的利器

Java 提供 7 種位運算符:~ & | ^ << >> >>>,直接操作二進制位,常用於權限掩碼、哈希算法、加密、網絡協議解析、高性能數學運算。本文通過圖解補碼原理、逐位演示、實戰代碼,徹底搞懂位運算。

核心知識:負數的二進制表示——補碼

Java 整型為有符號,負數以 正值補碼 存儲:

  1. 原碼:最高位符號位,其餘為絕對值(如 -5 → 1000...0101);
  2. 反碼:符號位不變,其餘位取反(1111...1010);
  3. 補碼:反碼 + 1(1111...1011) —— 這才是內存中真實存儲形式。

驗證:Integer.toBinaryString(-5) 輸出 32 位全 1 結尾 1011。

七大運算符逐位演示

運算符名稱規則示例 (5 & 6)結果
~按位取反0↔1~5 → 111...1010-6
&按位與同為1得10101 & 0110 = 01004
|按位或有1得10101 | 0110 = 01117
^按位異或異為1,同為00101 ^ 0110 = 00113
<<左移低位補0,高位丟棄5 << 1 = 101010 (×2)
>>算術右移高位補符號位-5 >> 1 = 111...1101-3 (÷2 向下取整)
>>>無符號右移高位補0-5 >>> 1 = 011...11012147483645 (大正數)

實戰技巧與經典面試題

1. 快速判斷奇偶 / 絕對值 / 交換變量

// 奇偶
boolean even = (n & 1) == 0;

// 絕對值 (不含 Integer.MIN_VALUE)
int abs = (n ^ (n >> 31)) - (n >> 31);

// 無臨時變量交換
a ^= b; b ^= a; a ^= b;

2. 權限掩碼 (參考 Linux rwx / 文章 111648)

int READ = 1 << 0;   // 0001
int WRITE = 1 << 1;  // 0010
int EXEC = 1 << 2;   // 0100

int userPerm = READ | WRITE; // 0011
boolean canRead = (userPerm & READ) != 0;
userPerm |= EXEC; // 添加執行權限
userPerm &= ~WRITE; // 移除寫權限

3. 判斷 2 的冪次 / 取模優化

// 是否為 2 的冪次
boolean isPowerOfTwo = (n > 0) && ((n & (n - 1)) == 0);

// 取模 2^n (n 為正整數)
int mod = x & ((1 << n) - 1); // 等價 x % (1<<n) 但更快

4. 移位實現乘除法 (編譯器自動優化)

x << 3  // x * 8
x >> 2  // x / 4 (負數向下取整)
x >>> 1 // 無符號除 2

5. 經典面試:不用比較運算符求兩數最大值

int max = a ^ ((a ^ b) & -(a < b)); // 利用符號位擴展
// 或
int diff = a - b;
int sign = (diff >> 31) & 1; // 1 表示 a

避坑指南

  • 移位距離取模:int 只看低 5 位 (mod 32),long 看低 6 位 (mod 64)。5 << 32 == 5;
  • 無符號右移陷阱:>>> 會將負數變為巨大正數,非邏輯除法場景慎用;
  • 補碼邊界:Integer.MIN_VALUE 絕對值溢出,Math.abs(-2147483648) == -2147483648;
  • Boolean 不支持位運算:只能用邏輯 && || !。

總結

位運算是通往底層優化的捷徑。掌握 補碼存儲、七大運算符規則、移位乘除、掩碼提取,配合 Integer.toBinaryString 調試,即可在權限系統、哈希分片、網絡協議、算法競賽中游刃有餘。記住:可讀性優先,必要時註釋位運算意圖。

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