整數的無符號編碼和有符號編碼


單個的位沒有實際意義,加上解釋才有實際意義.我們可以把位組合在一起,並且加上解釋以此賦予它意義.

無符號編碼表示的數 x >= 0

有符號編碼表示的數   min  <= x  and x <= max

當我們對數字的運算超出編碼所能表示的范圍就叫做溢出.

大多數計算機使用8位的塊(字節)作為最小的可尋址單位.機器級程序將內存視為非常大的數組,稱為虛擬內存.內存中的每一個字節都由唯一的數字來標識.稱為它的地址.

所有地址的集合即為虛擬地址空間.所以,對於32位的機器,虛擬地址空間地址范圍為0~0x8FFFFFFF-1,從0開始,需要減去1.

1.二進制轉16進制

   數學原理: 2^0+2^1+2^2+2^3 = 15

   在16進制中我們使用A~F來表示10,11,12,13,14,15,0~9 不變.

   由此,對一個二進制序列,我們只要從低位開始,每四個位取一個16進制數.如下.

   1111 0001  1000 的16進制表示法為 0xF18

   如果最后一次取數的二進制序列少於4位,高位補0,如下

   11 0001  1000 的16進制表示法為 0x318

   特別當x = 2^n次方時,轉16進制方法如下.

   因為有16進制的0代表4個二進制位.所以n = i + 4j. i = 0,1,2,3,16進制表示法為0x(2^i)(j個0)

   比如 二進制序列 100 0000 是 2^6, 6 = 2+1*4,16進制表示法為0x40 

 

 2.16進制轉二進制

    每一個16進制數,寫成4個二進制位

    比如.0x7F    0111 1111   

   

對於一個多字節的程序對象,必須建立倆個規則,對象的地址是什么,內存中如何排列這些字節,假設4字節int變量0x7FFFFFFF存儲是連續的,

有倆種排列方式.

1.低位在前

0x00   int的第一個字節 FF

0x01   int的第二個字節 FF

0x02   int的第三個字節 FF

0x03   int的第四個字節 7F

2.高位在前

0x00   int的第四個字節 7F

0x01   int的第三個字節 FF

0x02   int的第二個字節 FF

0x03   int的第一個字節 FF

 由此我們導出倆種程序對象在內存中排列的方式,大端法,小端法

1.有效的低字節在前,小端法

2.有效的高字節在前.大端法

影響到三個方面.

1.跨主機傳送數據,比如從使用大端排列的機器傳輸字節到小端排列的機器.如下,假設要傳送的數據是4個字節的int數字,0x7FFFFFFF(人的書寫形式),即2147483647

   大端機器的操作如下,將此int的四個字節,存入到一個bye[4]的數組內.[7F,FF,FF,FF,FF,FF,FF],

   小端機器接受到數據如下.[7F,FF,FF,FF,FF,FF,FF],那么小端機器認為低字節在前,即傳輸過來的數字為0xFFFFFFF7F.

2.閱讀表示整數數據的字節序列時字節順序也很重要.如下,考慮到反匯編代碼

  01 05 43 0b 20 00,這個是我們的書寫順序.

小端機器解釋的順序為 00 20 0b 43 05 01

大端機器解釋的順序為 01 05 43 0b 20 00

3.編寫規避正常類型系統的程序時,比如C里面的強制轉換和union

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

無符號數編碼和有符號整數補碼編碼

設一個二進制序列[xw-1.........x0]

   無符號編碼,最高位為負權,即符號位:

     X1 = xw-1*2w-1+..........+x0*20

  有符號補碼編碼為:

    X2 = -xw-1*2w-1+xw-2*2w-2+......................+x0*20

由以上倆個數學公式,可以導出有符號補碼編碼整數轉無符號編碼整數公式

  X2-X1 = -xw-1 * 2w-1 -  xw-1*2w-1 = -xw-1*2w

即 X1 = X2 + xw-1*2w    X2 = X1 - xw-1*2w

設,w = 4,考慮如下一個二進制序列[ 1 0 1 1]

它的無符號整數為 8+2+1=11,有符號整數為 -8+3=-5,

有 -5 = 11 - 1*2^4=11-16=-5

有 11 = -5 + 2^4 = -5 + 16 = 11

對倆個整數相加溢出,即超出編碼能容納的范圍,

無符號數加法

x +y = x+y 或者 x + y - 2w(即溢出位舍棄),考慮如下代碼

#include <iostream>
#include<limits.h>
using namespace std;




int main()
{
    cout << UINT32_MAX + 1 << endl;
}

運行結果為0.原理如下

0xFFFFFFFF + 1 = 0x1 00000000,溢出舍棄,即0x00000000 = 0x1 00000000 - 2^32 = 2^32 - 2^32

有符號數補碼加法

x + y = x +y 或者 x+y - 2(正溢出,整數相加變成負數) 或者 x+y + 2(負數相加變成整數)

int main()
{
    cout << INT32_MAX + 1 << endl; //2147483647 + 1 = 2147483648 - 2^32 = -2147483648
    cout << INT32_MIN - 1 << endl; // -2147483648 - 1 = -2147483649 + 2^32 = 2147483647
}

INT32_MAX 是 0x7FFFFFFF + 1 = 0x80000000 - 0x1 00000000 (2^32) = 0x80000000,第二行同理 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM