C++位操作符总结
1 #include <stdio.h> 2 #include <memory.h> 3 #include <malloc.h> 4 #define MaxBinLength 16 5 6 //获取无符号数的二进制,这是我自己写的,更简单的方法可以用bitset代替 7 char* getUnsignedBinary(unsigned int num) 8 { 9 int len = MaxBinLength -1; 10 char *bin = (char*)malloc((MaxBinLength + 1)*sizeof(char)); 11 memset(bin,'0',MaxBinLength); 12 bin[MaxBinLength] = 0; 13 while(num/2 != 0){ 14 bin[len--] = '0' + num%2; 15 num/=2; 16 } 17 if(num!=0) 18 bin[len--] = '1'; 19 return bin; 20 } 21 22 void flip(unsigned short num) 23 { 24 printf("位求反,运算符为 ~ ,功能简单,将操作数的每一个二进制位取反\n"); 25 printf("原值:%6d %s\n",num,getUnsignedBinary(num)); 26 printf("新值:%6d %s\n",~num,getUnsignedBinary(~num)); 27 printf("-------------------------\n"); 28 } 29 30 void left_shift(unsigned short num,unsigned short offset) 31 { 32 printf("左移运算,运算符为 << ,将操作数的二进制位向左移动指定的offset(%d)位数,offset必须小于原数的位数,右边新加的位以0填充\n",offset); 33 printf("原值:%6d %s\n",num,getUnsignedBinary(num)); 34 printf("新值:%6d %s\n",num<<offset,getUnsignedBinary(num<<offset)); 35 printf("-------------------------\n"); 36 } 37 38 void right_shift(unsigned short num,unsigned short offset) 39 { 40 printf("右移运算,运算符为 >> ,将操作数的二进制位向右移动指定的offset(%d)位数,offset必须小于原数的位数,\n\ 41 如果操作数无符号,左边新加的位以0填充,如果操作数有符号,右边新加的位可能以符号位填充,也可能以0填充,\n\ 42 具体依赖于机器,见注释\n",offset); 43 printf("原值:%6d %s\n",num,getUnsignedBinary(num)); 44 printf("新值:%6d %s\n",num>>offset,getUnsignedBinary(num>>offset)); 45 printf("-------------------------\n"); 46 } 47 48 void weiyu(unsigned short num,unsigned short num_1) 49 { 50 printf("位与,运算符为 & ,对两个操作数的每一个对应二进制位进行'与'运算,运算方式类似于&&运算\n"); 51 printf("原值:%6d %s\n",num,getUnsignedBinary(num)); 52 printf("原值:%6d %s\n",num_1,getUnsignedBinary(num_1)); 53 printf("新值:%6d %s\n",num&num_1,getUnsignedBinary(num&num_1)); 54 printf("-------------------------\n"); 55 } 56 57 void weihuo(unsigned short num,unsigned short num_1) 58 { 59 printf("位或,运算符为 | ,对两个操作数的每一个对应二进制位进行'或'运算,运算方式类似于||运算\n"); 60 printf("原值:%6d %s\n",num,getUnsignedBinary(num)); 61 printf("原值:%6d %s\n",num_1,getUnsignedBinary(num_1)); 62 printf("新值:%6d %s\n",num|num_1,getUnsignedBinary(num|num_1)); 63 printf("-------------------------\n"); 64 } 65 66 void weiyihuo(unsigned short num,unsigned short num_1) 67 { 68 printf("位异或,运算符为 ^ ,对两个操作数的每一个对应二进制位进行'异或'运算,两个位不同则为1,相同则为0\n"); 69 printf("原值:%6d %s\n",num,getUnsignedBinary(num)); 70 printf("原值:%6d %s\n",num_1,getUnsignedBinary(num_1)); 71 printf("新值:%6d %s\n",num^num_1,getUnsignedBinary(num^num_1)); 72 printf("-------------------------\n"); 73 } 74 75 void zhushi() 76 { 77 printf("注释:位操作符只能操作整数,这个整数可以是有符号的也可以是无符号的,\n\ 78 如果操作数为负数,则位如何处理其符号位依赖于机器,所以在一个环境中实现的\n\ 79 程序可能无法用于另一环境,因此强烈建议使用unsigned整数作为操作数\n\ 80 参考<<C++primer>>(人民邮电出版社第4版)155页\n"); 81 printf("-------------------------\n"); 82 } 83 84 int main() 85 { 86 unsigned short num = 125,num_1 = 26,offset = 3; 87 flip(num); 88 left_shift(num,offset); 89 right_shift(num,offset); 90 weiyu(num,num_1); 91 weihuo(num,num_1); 92 weiyihuo(num,num_1); 93 zhushi(); 94 return 0; 95 }
后来又自己试了一下,当在左移运算中,offset是可以大于操作数的长度的。当offset大一操作数长度的时候,操作的结果会自动更改整数类型,以容纳更多的位数,例如unsigned char可以变为short,short可以变为int等。
而右移运算中,无论offset为何值,操作结果的长度不会发证变化。
看demo,只是经过简单的验证。
1 #include <bitset> 2 #include <iostream> 3 #include <iomanip> 4 using namespace std; 5 6 #define uint8_t unsigned char 7 #define uint16_t unsigned short 8 #define uint32_t unsigned int 9 10 bitset<32> getBinary32(int num) 11 { 12 bitset<32> bit(num); 13 return bit; 14 } 15 16 bitset<8> getBinary8(uint8_t num) 17 { 18 bitset<8> bit(num); 19 return bit; 20 } 21 22 23 int main() 24 { 25 uint8_t a = 255; 26 //左移 27 cout<<"左移"<<endl<<"a="<<(int)a<<" "<<getBinary8(a)<<endl; 28 for(int i = 0;i<=24;i++) 29 { 30 if(i < 8) 31 { 32 uint16_t b = a<<i; 33 cout<<"b="<<setw(10)<<(unsigned short)b<<" "<<getBinary32(b)<<endl; 34 } 35 else 36 { 37 uint32_t b = a<<i; 38 cout<<"b="<<setw(10)<<(unsigned int)b<<" "<<getBinary32(b)<<endl; 39 } 40 } 41 42 //右移 43 cout<<"右移"<<endl<<"a="<<(int)a<<" "<<getBinary8(a)<<endl; 44 for(i = 0;i<=24;i++) 45 { 46 if(i < 8) 47 { 48 uint16_t b = a>>i; 49 cout<<"b="<<setw(10)<<(unsigned short)b<<" "<<getBinary32(b)<<endl; 50 } 51 else 52 { 53 uint32_t b = a>>i; 54 cout<<"b="<<setw(10)<<(unsigned int)b<<" "<<getBinary32(b)<<endl; 55 } 56 } 57 return 0; 58 }