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

Java長整型溢出原理:補碼表示法下為什麼0xFFFFFFFFFFFFFFFF等於-1

     編輯:程式設計綜合問答

現象

long x = 0xFFFFFFFFFFFFFFFFL; // 16個F
System.out.println(x); // 輸出 -1

核心原理:補碼表示法

Java 基本類型(byte/short/int/long)均採用**補碼**表示有符號整數。

以 4 位為例(擴展至 64 位同理)

為什麼全 1 是 -1?

補碼定義:負數 = 2^n - 絕對值 (n 為位數)

  • 4位:-1 = 16 - 1 = 15 = 1111₂
  • 64位:-1 = 2^64 - 1 = 18446744073709551615 = 0xFFFFFFFFFFFFFFFF

另一種理解:**模 2^n 同餘**。在模 16 意義下,15 ≡ -1。計算機定長存儲天然實現模運算。

推廣:0xFFFFFFFFFFFFFFFE = -2

1110 (二進制) = 14 (無符號) = -2 (補碼)
// 驗證:-2 + 2 = 0
  1110 (-2)
+ 0010 ( 2)
= 10000 → 截斷高位 → 0000 (0) ✓

Java 代碼驗證

public class OverflowDemo {
    public static void main(String[] args) {
        long max = Long.MAX_VALUE;  // 0x7FFFFFFFFFFFFFFF = 9223372036854775807
        long min = Long.MIN_VALUE;  // 0x8000000000000000 = -9223372036854775808
        
        System.out.println("max = " + max);
        System.out.println("max + 1 = " + (max + 1)); // 溢出變為 min
        System.out.println("min - 1 = " + (min - 1)); // 溢出變為 max
        
        // 位運算視角
        System.out.println("~0L = " + (~0L));        // -1
        System.out.println("~0L >>> 1 = " + (~0L >>> 1)); // 無符號右移
    }
}

關鍵結論

  • 補碼將「減法」轉化為「加法」:`a - b = a + (~b + 1)`
  • 符號位為 1 表示負數,但**數值由所有位共同決定**
  • Java 無無符號類型(除 `char`),所有整型運算均為補碼有符號運算
  • 溢出**不拋異常**,按模 2^n 環狀截斷,需開發者自行檢查(如 `Math.addExact`)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
二進制無符號值補碼有符號值說明
000000
000111
011177最大正數
10008-8最小負數
10019-7
111014-2
111115-1全 1 表示 -1