位运算的使用过程中有一些细节没注意就被坑了,于是记下备忘。
主要的位运算是:‘>>’, ‘<<’, ‘^’, ‘&’, ‘|’
- 移位运算:左移(‘<<’),右移(‘>>’)
uint16_t a = 0x00FF;
uint16_t b = a << 8;
uint16_t c = a >> 8;
cout << hex << a << endl;
cout << hex << b << endl;
cout << hex << c << endl;
//对应的输出是ff, ff00, 0
//
从结果可以看到的是移动n位的运算会在“整体移动,移出n位,空出的位填充0”
- 异或运算:‘^’、与运算:‘&’、或运算:‘|’
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
uint8_t a = 0xFF;
uint16_t b = 0xFF00;
uint16_t c = ((uint16_t)a) ^ b;
uint16_t d = ((uint16_t)a) & b;
uint16_t e = ((uint16_t)a) | b;
cout << hex << ((uint16_t)a) << endl;
cout << hex << c << endl;
cout << hex << d << endl;
cout << hex << e << endl;
//对应的输出是ff, ffff, 0, ffff
char a = 0xFF;
uint16_t b = 0xFF00;
uint16_t c = ((uint16_t)a) ^ b;
uint16_t d = ((uint16_t)a) & b;
uint16_t e = ((uint16_t)a) | b;
cout << hex << ((uint16_t)a) << endl;
cout << hex << c << endl;
cout << hex << d << endl;
cout << hex << e << endl;
//对应的输出是ffff, ff, ff00, ffff
从上面的两个例子可以总结出:“对于unsigned的无符号数进行数位扩大的强制类型转换时是填充的0,位有符号的数在相同条件下填充1”
再接着就是,与运算‘&’主要运用于提取(或清除)数据,或运算则‘|’是合并:
typedef unsigned short Unicode;
Unicode charToUni(char tmp[3])//将2个char合并为Unicode
{
return (((Unicode)tmp[0] << 8) | ((Unicode)tmp[1] & 0x00FF));
}//((Unicode)tmp[1] & 0x00FF))这里是因为char是有符号的,在运算时会自动填充“1”,故需要将高8位清零,并提取(保留)低8位
void UniToChar(Unicode word, char tmp[3])//将Unicode转换提取出2个char
{
tmp[0] = (word >> 8);
tmp[1] = (word & 0xFF);
tmp[2] = '\0';
return;
}