2011-09-01 139 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