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

十六進制轉十進制:有符號數與無符號數的區別詳解

     編輯:程式設計綜合問答

為什麼 0xFBB4 轉十進制會出現 -1100 和 64436 兩種結果?

這是一個經典的「有符號數 vs 無符號數」誤區。本文通過二進制補碼原理徹底講透。

現象重現

  • 輸入:FBB4 (16 進制)
  • 結果 A:64436 (無符號 16 位整數)
  • 結果 B:-1100 (有符號 16 位整數,short/int16)

二進制分析

F B B 4
1111 1011 1011 0100  ← 16 位二進制

無符號解讀 (Unsigned 16-bit)

直接按權展開:

1×2^15 + 1×2^14 + 1×2^13 + 1×2^12 +
1×2^11 + 0×2^10 + 1×2^9  + 1×2^8  +
1×2^7  + 0×2^6  + 1×2^5  + 1×2^4  +
0×2^3  + 1×2^2  + 0×2^1  + 0×2^0
= 64436

有符號解讀 (Signed 16-bit, Two's Complement)

  1. 最高位為 1 → 負數
  2. 取反加一求絕對值:
    原碼: 1111 1011 1011 0100
    取反: 0000 0100 0100 1011
    +1:   0000 0100 0100 1100  = 0x044C = 1100
        
  3. 結果:-1100

編程語言中的表現

語言/類型0xFBB4 結果說明
C/C++ unsigned short64436無符號
C/C++ short / int16_t-1100有符號補碼
Java short-1100固定有符號
Python int.from_bytes(b'\\xfb\\xb4', 'big', signed=True)-1100顯式指定
JavaScript new DataView(buf).getInt16(0)-1100有符號讀取

如何得到你想要的結果

想要 -1100(當作有符號 16 位):

// C/C++
int16_t val = (int16_t)0xFBB4;  // -1100

// Java
short val = (short)0xFBB4;      // -1100

// Python
val = int.from_bytes(bytes.fromhex('FBB4'), 'big', signed=True)

想要 64436(當作無符號 16 位):

// C/C++
uint16_t val = 0xFBB4;  // 64436

// Java (無無符號 short,用 int 接收)
int val = 0xFBB4 & 0xFFFF;  // 64436

// Python
val = int.from_bytes(bytes.fromhex('FBB4'), 'big', signed=False)

核心結論

同一組二進制位,賦予「有符號」或「無符號」語義,得到完全不同的數值。一定要明確數據類型定義,不要憑直覺轉換。網絡協議、文件格式、硬體寄存器文檔會明確註明是 signed 還是 unsigned。

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