基础位操作

2019-04-13 11:04发布

      最近,学校模电课上学习了数字电路,接触了一些位运算有关的东西,觉得挺好的,就想记下来做个笔录。 Title:基础位运算 Author:zhuangyue_lala Key words:位运算,C++         在学校开设的C++课上老师并没有讲位运算,当初觉得挺复杂的,也没有关注这一点。最近在学习了模电课之后,从计算机组成及操作方面对位运算有了一定了解之后,深刻觉得位操作是个好东西,于是就来查查资料,自学并梳理了一下。        本文决定从以下几个方面展开:               (一)二进制               (二)基础位操作运算符与运算规则               (三)位运算的简单应用        (一)首先,第一方面。什么是二进制?计算机处理二进制数的方法。以一个字节为例,一个字节有8byte,可以表示256个整数,从-128~127,以最高位为符号位,0代表整数,1代表负数,定义0的二进制数为00000000,那么1的二进制就是00000001,而01111111就代表127,从00000001到01111111就是从1到127。那么负数是怎么存的呢?是不是就是将正数符号位换成1就可以了呢?这样的话你会发现,你取不到-128。要知道负数在计算机中是怎样存的,先要介绍一下源码,反码,补码,以-1为例,-1的原码是00000001,就是它绝对值的二进制数,将每一个位取反就得了它的反码,再将反码+1就得到了补码。-1的补码就是11111111,由此,我们发现从10000000到11111111分别表示-128到-1。负数再计算机中存储方式就是补码。所以对其位操作的时候,需要对其补码进行操作,千万不要用源码。        (二)接下来,就是常见的位运算符号以及法则。这里给出一个表格。                   
               这里强调一下:1、只有取反是 单目运算符,其他的都是双目运算符                                          2、位运算的优先级比较低,所以最好能加上括号,以免得出不知所以然的值。                                          3、位操作只能处理整形数,不能处理double和float,这是由存储方式决定的                                          4、在移位操作中,左移都是低位补零,右移根据编译器决定,高位补符号位和高位补零两种。前一种叫算数移位,后一种叫逻辑移位。一般在VC,vs采用的就是算数移位。               (三)接下来就是一些实用的位运算小技巧,虽然不能起到实际上的质变,也能在同学面前装装逼的,当然实际上的目的是学着用一下位运算。                          1、判断奇偶。                                一个二进制数判断奇偶太简单了,末尾0偶,1奇,没有别的可能了,所以,只要找到这个数的最低位就可以了。可以用if(a&1)代替if(a%2)来寻找奇数。                          2、交换两数。一般的写法如下:                                 void Swap(int &a, int &b) { if (a != b) { int c = a; a = b; b = c; } }                              那,可不可以不用引入参数就可以完成数据交换!,位操作写法如下: void Swap(int &a, int &b) { if (a != b) { a ^= b; b ^= a; a ^= b; } }                            首先要知道,一个数和自己异或是零。一个数和零异或是它本身。                             第一步,a=(a^b);                             第二步,b=b^(a^b),由于异或运算具有交换性,所以第二部等同于b^b^a=a,此时b就得到了a的值了。                             第三步,a=(a^b)^b,和刚才一样,注意此时b已经是a的值了,由此a就得到了b的值。                        3、取反。                             变换符号就是负变正,正变负。在操作之前要判断是正是负。用移位操作来完成,将a>>31,a为正数的话,表达式的值为0,否则表达式的值为1。                             将一个整数取反然后加一就得到相反数。                             比如7=00000111,~7=11111000,+1之后,11111001,这就是-7了哈                             再回来一遍11111001取反,00000110,加一00000111,得7。                             很奇妙不是吗? int SignReversal(int a) { return ~a + 1; } int main() { printf("对整数变换符号 --- by MoreWindows( http://blog.csdn.net/MoreWindows ) --- "); int a = 7, b = -12345; printf("%d %d ", SignReversal(a), SignReversal(b)); return 0; }                      4、取绝对值,跟上一个基本一样,不多说了。 其实,位运算最大的优点就是压缩运行空间,试想,位操作是直接对byte位进行操作,比用字节位操作要整整轻松了八分之一,很厉害。但是位操作也不是哪都用的,因为它会让代码的可读性变差很多,在写最底层程序的时候,用位还是挺多的。这就是这次学习的收获。