首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 位移運算符詳解:>> 有符號右移 vs >>> 無符號右移,二進制圖解與實戰陷阱

     編輯:程式設計綜合問答

核心區別一覽

運算符名稱高位補齊規則適用類型典型場景
>>算術右移 / 有符號右移複製符號位(正數補 0,負數補 1)所有整數類型保持正負號的除以 2^n
>>>邏輯右移 / 無符號右移固定補 0所有整數類型(Java 特有)位掩碼處理、無符號數運算

二進制圖解(以 8 位為例)

原數: 1001 1101  (十進制 -99,最高位 1 表示負數)

>> 1 (算術右移):
步驟1: 1100 1110  (符號位 1 補齊)
步驟2: 1110 0111  (再右移 1 位)
結果: 1110 0111  (十進制 -25,符號保持)

>>> 1 (邏輯右移):
步驟1: 0100 1110  (固定補 0)
步驟2: 0010 0111  (再右移 1 位)
結果: 0010 0111  (十進制 39,變為正數!)

為什麼 Java 有 >>> 而 C/C++ 沒有?

  • Java 無 unsigned 關鍵字,所有整數類型均為有符號
  • C/C++ 有 unsigned int,對無符號數右移編譯器自動執行邏輯右移
  • Java 需顯式運算符區分兩種語義

實戰陷阱與最佳實踐

陷阱 1:負數右移後判斷奇偶

int n = -5; // 1111...1011
boolean odd = (n & 1) == 1; // 正確:最低位決定奇偶
boolean odd2 = (n >> 1) & 1; // 錯誤!算術右移補 1,破壞原意

陷阱 2:哈希碼/索引計算

// 錯誤:負數 hashCode 導致負索引
int index = key.hashCode() >> 1; 

// 正確:無符號右移保證非負
int index = key.hashCode() >>> 1; 
// 或更常用:
int index = (key.hashCode() & 0x7FFFFFFF) % size;

陷阱 3:長整型合成

long combined = ((long)high << 32) | (low & 0xFFFFFFFFL);
// 取高 32 位時必須用 >>>,否則符號擴展導致錯誤
int high = (int)(combined >>> 32);

左移運算符 <<

  • 只有 <<,無 <<<
  • 低位補 0,高位丟棄
  • 等同於乘以 2^n(溢出按模 2^32/2^64 環繞)

面試必考點

  1. -1 >> 1 = ? (答案:-1,全 1 右移仍全 1)
  2. -1 >>> 1 = ? (答案:2147483647,即 0x7FFFFFFF)
  3. 5 >> 2 vs 5 >>> 2 (正數時結果相同,均為 1)
  4. 如何用位運算實現無符號整數除以 2? (n >>> 1)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved