2013-07-16 44 views
1

说我有存储2个字节的缓冲区:按位开关最显著和至少显著字节

char *buf=new char[4]; 
// 00000010 00000000 (.. other stuff ..) 

我想要做的就是切换最少,最显著字节,并将该值存储在一个变量是什么。试图这样做如下:

short len=buf[1]; 
len <<= 8; 
len |= buf[0]; 
    // Result, as expected: 00000000 00000010 

它的工作原理细粉,除非最显著字节(BUF [0])是> = 128,这使得所述或运算符(|)填充短的一半1的。例如:

Original: 10000110 00000000 
Should be: 00000000 10000110 
But is: 11111111 10000110 

谢谢(哦,我在读从文件与file.read(字节...,4); - 甚至都不知道这是有关)

+8

如果要操纵位,请使用无符号类型。如果您想操作数字,请使用签名类型。 –

+0

如果您不熟悉按位操作,则可以尝试使用std :: bitset。如果让你使用像数组一样的位。完成后,您可以将其转换回整数。 –

回答

6

您的实施显然使用有符号数字的two's complement表示。使用无符号值而不是

unsigned char * buf = new unsigned char[2]; 
... 

unsigned short len=buf[1]; 
len <<= 8; 
len |= buf[0]; 
+0

+1 阿门是正确的。你实际上是在执行算术而不是逻辑转换。见[这里](http://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts)...:D – someone

+2

如果'char'被签名,这将无济于事; 'buf [0]'在'| ='提升为'int'时仍然会被扩展。您需要更改'buf'的类型,而不是'len',以防止符号扩展。 –

+0

我听说右移做标记扩展,但没有左移。 –

0

试试这个:

unsigned short buf; 
... 
buf = buf << 8 | buf >> 8; 

或者只是进行置换:

char buf[2]; 
char tmp; 
... 
tmp = buf[0]; 
buf[0] = buf[1]; 
buf[1] = tmp; 

我希望这有助于!

0
buff = 11001010 01011100; 
//copy this buff, I am writing it directly below 

copy_of_buff = 11001010 01011100; 
buff_hi = (buff >> 8); //Hence after this exec, buff_hi = 00000000 11001010 
buff_lo = (copy_of_buff << 8); //Hence after this exec, buff_lo = 01011100 00000000 

out_buff = (buff_hi)||(buff_lo); //Hence after this exec, out_buff = 01011100 11001010