# C语言 位运算和进制转换 ## 一,& (按位与)、| (按位或)、^ (按位异或)、~ (按位取反)、>> (按位右移)、<< (按位左移) (1)按位与运算符(&) “a&b”是指将参加运算的两个整数a和b,按⼆进制位进⾏“与”运算。 运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1; 即:两位同时为“1”,结果才为“1”,否则为0 (2)按位或运算符(|) 参加运算的两个对象,按⼆进制位进⾏“或”运算。 运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1; 即 :参加运算的两个对象只要有⼀个为1,其值为1。 (3)按位异或运算符(^) 参加运算的两个数据,按⼆进制位进⾏“异或”运算。 运算规则:0 ^ 0=0; 0 ^ 1=1; 1^ 0=1; 1^1=0; 即:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。 ^(按位异或): 概念上来讲就是二进制上按每一位(0或1)进行异或运算。 异或运算简单讲就是相同就为假,不同为真。 7 ^ 3 = 0000 0111 ^ 0000 0011 = 0000 0100 = 4 ~(按位取反): 概念上来讲就是二进制上按每一位(0或1)进行取反运算。 取反运算简单讲就是0变1,1变0。 ~7 = ~0000 0111 = 1111 1 000 = 0xf8 = 248 (无符号) >>(按位右移): 概念上来讲就是二进制上按每一位(0或1)进行右移运算。 右移运算简单讲就是将二进制的位整体向右移动。 7 >> 2 = 0000 0111 >> 2 = 0000 0001 = 1 // 这里向右移动了2位,最低位的两个1被抹去。 <<(按位左移): 这个就不说了,与上面右移方向的相反。 ## 二,进制转换 进制转换的方法是:二进制数,十六进制数可以采用按权展开法转化为十进制数,十进制转化为R进制要分为两部分,其中整数部分要除R取余,直到商为0,小数部分要乘R取余直到得到整数。 用按权展开法把一个任意R进制数 an an-1 …a1a0 . a-1 a-2…a-m 转换成十进制数,其十进制数值为每一位数字与其位权之积的和。 an×R n + an-1×R n-1 +…+ a1×R 1 + a0×R 0 + a-1 ×R-1+ a-2×R-2+ …+ a-m×R-m 十进制转化成R进制 十进制数轮换成R进制数要分两个部分: 整数部分:除R取余数,直到商为0,得到的余数即为二进数各位的数码,余数从右到左排列(反序排 列)。 小数部分:乘R取整数,得到的整数即为二进数各位的数码,整数从左到右排列(顺序排列)。 十进制 二进制数 1 0 2 10 3 11 4 100 5 101 6 110 7 111 8 1000 9 1001 10 1010 1 0 2 10 4 100 8 1000 十进制 --->>> 二进制数 15 ===>>> 8 + 4 + 2 + 1 === 1111 二进制数 --->>> 十进制 1111 ===>>> 2^3 + 2^2 + 2^1 + 2^0 === 8+4+2+1 === 15/F c++ std::bitset #include <bitset> bitset<4> foo (string("1001")); bitset<4> bar (string("0011")); bitset<4> foo ("1011"); foo[i] = 0; foo.flip(); foo.flip(i); foo.set(); foo.set(i); foo.set(i,0); foo.reset(); foo.reset(i); bitset<8> foo ("10011011"); string s = foo.to_string(); unsigned long a = foo.to_ulong(); unsigned long long b = foo.to_ullong();