2016-06-11 51 views
3

我有兩個函數打印二進制32位數字。 第一個將數字分成字節並從最後一個字節開始打印(從整數的第25位開始打印)。 第二個更直接,從數字的第一位開始。 在我看來,這些函數應該有不同的輸出,因爲它們以不同的順序處理比特。但是輸出是一樣的。爲什麼?爲什麼這兩個函數打印一個整數的二進制表示有相同的輸出?

#include <stdio.h> 

void printBits(size_t const size, void const * const ptr) 
{ 
    unsigned char *b = (unsigned char*) ptr; 
    unsigned char byte; 

    int i, j; 

    for (i=size-1;i>=0;i--) 
    { 
     for (j=7;j>=0;j--) 
     { 

      byte = (b[i] >> j) & 1; 
      printf("%u", byte); 
     } 
    } 
    puts(""); 
} 

void printBits_2(unsigned *A) { 

    for (int i=31;i>=0;i--) 
    { 
    printf("%u", (A[0] >> i) & 1u); 
    } 
    puts(""); 
} 

int main() 
{ 
    unsigned a = 1014750; 
    printBits(sizeof(a), &a); // ->00000000000011110111101111011110 
    printBits_2(&a); //   ->00000000000011110111101111011110 
    return 0; 
} 
+2

這兩個函數都以最高有效位從左到右輸出位。 –

+2

您對平臺的[endianness](https://en.wikipedia.org/wiki/Endianness)做了一個假設。 –

回答

3

這兩個函數都會將數字的二進制表示從最高有效位打印到最低有效位。今天的PC(和大多數其他計算機體系結構)使用所謂的Little Endian格式,其中多字節值首先以最低有效字節存儲。

這意味着,存儲在地址0x1000 32位值0x01020304看起來像這樣的記憶:

+--------++--------+--------+--------+--------+ 
|Address || 0x1000 | 0x1001 | 0x1002 | 0x1003 | 
+--------++--------+--------+--------+--------+ 
|Data || 0x04 | 0x03 | 0x02 | 0x01 | 
+--------++--------+--------+--------+--------+ 

因此,在小端架構,從MSB印刷價值的位LSB相當於服用其字節按相反順序排列,並將每個字節的位從MSB打印到LSB。

1

它們不按不同順序處理位。這裏有一個視覺:

Bytes: 4      3      2      1 
Bits: 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 
Bits: 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 

事實上,輸出是一樣的,從這些功能都告訴你,你的平臺使用小端編碼,這意味着最顯著字節排在最後。

前兩行顯示了第一個函數如何在您的程序中工作,最後一行顯示了第二個函數的工作方式。

然而,第一功能將在使用大端編碼並輸出位中的第三行中示出該順序的平臺失敗:

Bytes: 4      3      2      1 
Bits: 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 
Bits: 8 7 6 5 4 3 2 1 16 15 14 13 12 11 10 9 24 23 22 21 20 19 18 17 32 31 30 29 28 27 26 25 
+0

@HolyBlackCat是的,我的歉意。我讓他們混淆在我的腦海中,我會改變答案。 –

2

這是預期的結果時:

1)您可以使用這兩個函數以二進制形式打印單個整數。

2)您的C++實現在little-endian hardware platform上。

更改其中一個因素(適當調整printBits_2),結果將會不同。

0

對於printbits1函數,它採用uint32指針並將其指定給一個char指針。

unsigned char *b = (unsigned char*) ptr; 

如今,在大端處理器,b[0]將指向UINT32值的最高顯著字節。內循環以二進制形式打印此字節,然後b [1]將指向ptr中的下一個最重要的字節。因此,此方法首先打印uint32值MSB。

至於printbits2,使用的是

unsigned *A 

即一個unsigned int。該循環從31運行到0,並以二進制形式打印uint32值。

相關問題