位运算

来源:互联网 发布:jquery 1.10.2.min.js 编辑:程序博客网 时间:2024/06/05 14:00
1,“与”运算 符号 &   0000 0101&0000 0011=0000 0001    即 1&0=0,1&1=1,0&0=0。
应用:常用于清零操作。for(int i=1;i<=n;i++) a[i]=a[i]&0;
2,“或”运算 符号 |     0000 0101&0000 0011=0000 0111   即1|1=1,1|0=1,0|0=0。
       应用:常用于置1操作,就是把二进制的某几位变成 1。
3,“非"  运算 符号~   (是单目运算符) ~0101=1010.
4,“异或”运算 符号^  相同的为0  不相同的为1   0000 0101^0000 0111=0000 0010
 性质:1、交换律    a^b=b^a
 2、结合律     (a^b)^c=a^(b^c)
 3、对于任何数x,都有x^x=0,x^0=x
 4、自反性 A XOR B XOR B = A xor  0 = A    a^b^a=b,a^b^b=a
 对于第4条性质很容易由前3条性质得出
应用第4条性质可以实现数字的交换 比如 交换a b 的值   a=a^b;b=a^b;a=a^b;
对比我们以前交换值的方法   t=a;a=b;b=t; 要高端一些,也应该能快一些
当然交换值得方法还有    a=a+b;b=a-b;a=a-b;
这里有道面试题:

1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现
一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空
间,能否设计一个算法实现?

解法一、显然已经有人提出了一个比较精彩的解法,将所有数加起来,减去1+2+...+1000的和。
这个算法已经足够完美了,相信出题者的标准答案也就是这个算法,唯一的问题是,如果数列过大,则可能会导致溢出。(由于题目的特殊可以用等差数列求和,也可以用高斯的方法)
解法二、异或就没有这个问题,并且性能更好。
将所有的数全部异或,得到的结果与1^2^3^...^1000的结果进行异或,得到的结果就是重复数。
证明方法二:设要求的数为 n 则将所有的数全部异或得1^2^3^……^1000^n^n。而n^n=0  又由 一个数异或0等于本身 即1^2^3^……^1000^n^n=1^2^3^……^1000=T(这里为1~1000的数 没有n)从而 T^(1^2^3^……^1000)求得n的值
5,“左移”运算 符号<<  将二进制的每位像左移动  a<<2为向左移动2位 右面补两个0 相应的十进制数扩大4倍
6,“右移”运算 符号>>  将二进制的每位向右移动  a>>1为向右移动1位 左面补一个0 相应的十进制数缩小2倍(1/2)
这里左移还是右移 对负数的处理比较特别
负数用其正值的补码形式表示
原码:即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小
反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
例如 求-14的二进制   (在8位计算机中)现在流行的都是32位的
1 000 1110->1111 0001->1111 0010(-14)
-14<<2  =  1100 1000->1100 0111->1011 1000=-56 


0 0
原创粉丝点击