2011-09-01 140 views
12

我有興趣編寫一個函數getMyByteChunkFunction,它接受兩個參數 - 一個32位整數和一個字節偏移量(0,1,2或3),然後將相應的字節返回的32位整數。例如,假設該整數:按位運算符從32位獲取字節

  (3)   (2)  (1)  (0) ---byte numbers 
int word = 10101010 00001001 11001010 00000101 

函數調用getMeByteChunkFunction(word, 2)返回00001001

但是,我受限於我可以使用的按位運算符。我只允許使用>>,<<恰好一個減法。我知道如何使用AND和XOR來做到這一點,但我不知道如何在這裏使用減法。有任何想法嗎?

+0

標籤功課(不得不放棄「邏輯」,因爲最多5個標籤。) –

+0

@JBentley:我兩年前作出評論。 –

回答

6

你可以做到這一點只是換擋。向左移動以擺脫左側的位,然後向右移動以擺脫右側的位並將所需的字節移動到最不重要的位置。

+0

如果bitshift是簽名保留的,這不會有問題嗎? – templatetypedef

+2

你可以先將它轉換爲無符號的嗎?這將照顧它。如果沒有,請使用templatetypedef的答案。 –

25

一個想法如下。假設你有一個四字節的值,像這樣的:

aaaaaaaa bbbbbbbb cccccccc dddddddd 

讓我們假設你想要得到字節bbbbbbbb出於此。如果由兩個字節右移,你

???????? ???????? aaaaaaaa bbbbbbbb 

此值等於你想要什麼,只是在頂部有???????? ???????? aaaaaaaa(因爲我們不知道如果移位被符號保留或不,因爲我不知道你的價值是否未簽名。)不過,不用擔心;我們可以擺脫這些未知的值和a字節。爲了擺脫頂部,假設你右移另一個字節,給人

???????? ???????? ???????? aaaaaaaa 

現在,左移一個字節,獲得

???????? ???????? aaaaaaaa 00000000 

如果你那麼做減法,你會得到

???????? ???????? aaaaaaaa bbbbbbbb 
- ???????? ???????? aaaaaaaa 00000000 
--------------------------------------- 
    00000000 00000000 00000000 bbbbbbbb 

而且,你有你想要的價值!

我將實際的代碼作爲練習留給讀者。別擔心,這不是特別困難。 :-)

+0

你似乎有你的左右混淆? –

+0

@Tom Zych-哎呀!感謝您的支持。我很難指導。 :-) – templatetypedef

+0

@templatetypedef,在帖子後面的錯誤評論...我最好休息一會兒。 ;-)。 –

0

這裏是代碼:

#include <stdio.h> 

int main() { 
    unsigned long n = 0xAA09CA05L; /* 10101010 00001001 11001010 00000101 */ 
    printf("%08lx\n", n); /* input */ 
    printf("%02lx\n", ((n<<8)>>24)); /* output */ 
    return 0; 
} 

和輸出:

aa09ca05 
09 
+0

如果你只是用很長的時間就不會在大多數編譯器上工作。.. .. – Voo

+0

ANSI/ISO C規範說長必須至少4字節。你知道任何ANSI兼容的C編譯器,它不會工作嗎? –

+3

http://meta.stackexchange.com/questions/10811/how-to-ask-and-answer-homework-questions –

1

有一個非常聰明的把戲對於這一點,我使用的對象轉換成字符的字符串(傳輸作爲流):

//WhichByte should really be an enum to avoid issues 
//Counts as 0, 1, 2 or 3 
//Modify as unsigned or signed char (for return type and pointer type) as needed 
#define BYTE_TYPE unsigned char 
BYTE_TYPE GetByte(const unsigned int Source, const unsigned char WhichByte) 
{ 
    if(WhichByte < 0){return 0;} 
    if(WhichByte >= sizeof(Source)){return 0;} 

    //Converts source into the appropriate pointer 
    BYTE_TYPE * C_Ptr = (BYTE_TYPE *)&Source; 
    return *(C_Ptr+WhichByte); 
} 
#undef BYTE_TYPE 

簡而言之,上述將源視爲4個獨立的字符(其通常是onl y大小爲1個字節),並且指針允許您將其視爲內存段。你在返回之前解除它的引用。

無論什麼目的(甚至商業)使用它。

壓縮格式?

#define GetByte(X,Y) (*(((unsigned char *)&X)+Y)) 
2

下面的代碼也應該回答這個問題。

#include <stdio.h> 

int getByte(int x, int n); 

void main() 
{ 
    int x = 0xAABBCCDD; 
    int n; 

    for (n=0; n<=3; n++) { 
     printf("byte %d of 0x%X is 0x%X\n",n,x,getByte(x,n)); 
    } 

} 

// extract byte n from word x 
// bytes numbered from 0 (LSByte) to 3 (MSByte) 
int getByte(int x, int n) 
{ 
    return (x >> (n << 3)) & 0xFF; 
} 

輸出是

byte 0 of 0xAABBCCDD is 0xDD 
byte 1 of 0xAABBCCDD is 0xCC 
byte 2 of 0xAABBCCDD is 0xBB 
byte 3 of 0xAABBCCDD is 0xAA 

概念可以基於templatetypedef的解釋說明和擴大如下。

(3)  (2)  (1)  (0) 
aaaaaaaa bbbbbbbb cccccccc dddddddd 

{(3),(2),(1),(0)} --> {(3)} 
    ???????? ???????? ???????? aaaaaaaa // x>>(3*8) where 3 == n 
& 00000000 00000000 00000000 11111111 // 0xFF 
    ----------------------------------- 
    00000000 00000000 00000000 aaaaaaaa // (x >> (8 * n)) & 0xFF 

{(3),(2),(1),(0)} --> {(2)} 
    ???????? ???????? aaaaaaaa bbbbbbbb // x>>(2*8) where 2 == n 
& 00000000 00000000 00000000 11111111 // 0xFF 
    ----------------------------------- 
    00000000 00000000 00000000 bbbbbbbb 

{(3),(2),(1),(0)} --> {(1)} 
    ???????? aaaaaaaa bbbbbbbb cccccccc // x>>(1*8) where 1 == n 
& 00000000 00000000 00000000 11111111 // 0xFF 
    ----------------------------------- 
    00000000 00000000 00000000 cccccccc 

{(3),(2),(1),(0)} --> {(0)} 
    aaaaaaaa bbbbbbbb cccccccc dddddddd // x>>(0*8) where 0 == n 
& 00000000 00000000 00000000 11111111 // 0xFF 
    ----------------------------------- 
    00000000 00000000 00000000 dddddddd 

Note (x >> (8 * n)) & 0xFF is equivalent to (x >> (n << 3)) & 0xFF. 

64 32 16 8 4 2 1 
---------------- 
0 0 0 0 0 1 1 // (n==3) 
0 0 1 1 0 0 0 // (n*8==n<<3==24) 
---------------- 
0 0 0 0 0 1 0 // (n==2) 
0 0 1 0 0 0 0 // (n*8==n<<3==16) 
---------------- 
0 0 0 0 0 0 1 // (n==1) 
0 0 0 1 0 0 0 // (n*8==n<<3==8) 
---------------- 
2
result = (word >> (n_byte << 3)) & 0xFF; 
+0

請解釋一下? – 2015-01-08 21:58:56