基础位操作

来源:互联网 发布:appstore不能更新软件 编辑:程序博客网 时间:2024/06/03 21:06

      最近,学校模电课上学习了数字电路,接触了一些位运算有关的东西,觉得挺好的,就想记下来做个笔录。

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 )  ---\n\n");      int a = 7, b = -12345;      printf("%d  %d\n", SignReversal(a), SignReversal(b));      return 0;  }
                      4、取绝对值,跟上一个基本一样,不多说了。

其实,位运算最大的优点就是压缩运行空间,试想,位操作是直接对byte位进行操作,比用字节位操作要整整轻松了八分之一,很厉害。但是位操作也不是哪都用的,因为它会让代码的可读性变差很多,在写最底层程序的时候,用位还是挺多的。这就是这次学习的收获。



1 0
原创粉丝点击