2011-09-01 43 views
12

Tôi quan tâm đến việc viết một hàm getMyByteChunkFunction chấp nhận hai tham số - một số nguyên 32 bit và một byte bù đắp (0, 1, 2 hoặc 3), sau đó trả về byte tương ứng của số nguyên 32 bit. Ví dụ: cho số nguyên này:Toán tử bitwise để lấy byte từ 32 bit

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

gọi hàm getMeByteChunkFunction(word, 2) trả về 00001001.

Tuy nhiên, tôi bị giới hạn ở các toán tử bitwise mà tôi có thể sử dụng. Tôi chỉ được phép sử dụng >>, <<chính xác một lần trừ. Tôi biết làm thế nào để làm điều này bằng cách sử dụng AND và XOR, nhưng tôi không biết làm thế nào tôi muốn sử dụng một phép trừ ở đây. Bất kỳ ý tưởng?

+0

Tagged as bài tập về nhà (phải thả "logic" vì max 5 thẻ.) –

+0

@JBentley: Tôi đã bình luận rằng hai năm trước đây. –

Trả lời

6

Bạn có thể làm điều đó chỉ bằng cách dịch chuyển. Di chuyển sang trái để loại bỏ các bit ở bên trái, sau đó dịch chuyển sang phải để loại bỏ các bit ở bên phải và di chuyển byte mong muốn vào vị trí ít quan trọng nhất.

+0

Điều này không có vấn đề nếu bithift là dấu hiệu bảo quản? – templatetypedef

+2

Bạn có được phép truyền nó trước tiên không? Điều đó sẽ chăm sóc nó. Nếu không, đi với câu trả lời của templatetypedef. –

25

Một ý tưởng là như sau. Giả sử rằng bạn có một giá trị bốn byte như thế này:

aaaaaaaa bbbbbbbb cccccccc dddddddd 

Giả sử rằng bạn muốn nhận được các byte bbbbbbbb trong số này. Nếu bạn thay đổi quyền bởi hai byte, bạn sẽ có được

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

Giá trị này tương đương với những gì bạn muốn, ngoại trừ việc ở phía trên nó có ???????? ???????? aaaaaaaa (vì chúng tôi không chắc chắn nếu sự thay đổi là ký bảo quản hay không , vì tôi không biết liệu giá trị của bạn chưa được ký hay không.) Tuy nhiên, đừng lo lắng; chúng tôi có thể loại bỏ các giá trị không xác định này và byte a. Để thoát khỏi phía trên, giả sử rằng bạn chuyển ngay một byte, cho

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

Bây giờ, thay đổi trái một byte để có được

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

Nếu bạn sau đó làm phép trừ này, bạn sẽ có được

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

Và voil & agrave; ... bạn có giá trị bạn muốn!

Tôi sẽ để lại mã thực tế làm bài tập cho người đọc. Đừng lo lắng; nó không đặc biệt khó. :-)

+0

Bạn dường như đã trộn lẫn trái và phải của bạn? –

+0

@Tom Zych- Rất tiếc! Cảm ơn vì đã bắt được điều đó. Tôi rất tệ khi đưa ra chỉ dẫn. :-) – templatetypedef

+0

@templatetypedef, bình luận sai theo bài ... tôi nghỉ ngơi tốt hơn một chút. ;-). –

0

đây là mã:

#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; 
} 

và đầu ra:

aa09ca05 
09 
+0

Sẽ không hoạt động trên hầu hết các trình biên dịch nếu bạn chỉ sử dụng dài mặc dù .. – Voo

+0

Đặc điểm kỹ thuật ANSI/ISO C nói rằng tôi phải dài ít nhất 4 byte. Bạn có biết bất kỳ trình biên dịch C tương thích ANSI nào trên đó nó sẽ không hoạt động? –

+3

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

1

Có một mẹo rất thông minh cho điều này, mà tôi sử dụng để chuyển đổi đối tượng thành chuỗi char (để truyền dưới dạng luồng):

//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 

Tóm lại, nguồn trên xử lý là 4 ký tự riêng biệt (thường là onl y 1 byte có kích thước) và con trỏ cho phép bạn xem nó như một phần bộ nhớ. Bạn dereference nó trước khi trở về.

Sử dụng bất kỳ mục đích nào (thậm chí là thương mại).

Định dạng nén?

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

Mã sau cũng nên trả lời câu hỏi.

#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; 
} 

Đầu ra là

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

Khái niệm này có thể được giải thích dựa trên templatetypedef 's giải thích và mở rộng như sau.

(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

Giải thích, vui lòng? –

Các vấn đề liên quan