位运算属于基础,这里总结一下。若用到位运算,基本是涉及到数据的巧妙操作的地方。
本文讲述的位运算有:
左移,右移,位与,或,取反,异或。
移位
对于一个数来说,它所在的位置决定了该数所代表的大小,即位权。权重越大,代表的数越大。对于二进制的数来说,不同位上的1表示的数相差倍数为2^n。那么,就有移位操作其实是对数的 x2或者 /2 的问题。
当然,在我们的脑海中肯定能清晰的模拟该问题,但是,对于实际的环境,特别是计算机来说,是存在一定的限制的。
首先,需明白这个数表示的什么,对于一个Byte来说,存储的值为0xFF就表示255了?那么,负数该怎么表示?这是另外一个问题,此处不说明,默认为知道。
不考虑其他因素:
左移 << 低位补0 相当于 x2
右移 >> 去掉最低位,相当于/2
与 或
按位与 & 故名思意,一位一位的做逻辑与。
基本规则为:
与:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
俗话说的好,全1为1.有点像0和1的乘法。
或:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
根据上面的来:全0为0,有1为1.
现在操作的数据基本都是以Byte为最小单位,所以用到的很多都是Byte型数据。对于Byte型数据中某一位处理,有:
A & ~(1<<n) //某一位写0
A | (1<<n) //某一位写1
当然,对于位操作,有一个位定义。可以通过这种方式来对某个数据的位做单独的读写操作。基本用在单片机上……
取反
上面已经涉及到这一部分的内容了,不在这里说明。对位取反。0->1,1->0
异或
异或有可能陌生一点,这里给出0,1的异或逻辑关系:
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
相同为0,不同为1.还有一种说法为半加法。
对于异或操作,有一个经典的交换数据的例子,即:
交换两数A,B,不使用额外的变量,现在都会如下:
A ^= B
B ^= A
A ^= B
这样两数就交换了。(这里不讨论限制性问题。)
为什么可以这样做?是因为 A ^= B 扩展即: A = A ^ B。
在后两行参与运算的A均为A ^ B。
如果将数据扩展为Byte型,有如下:
A ^ 0x00 = A
A ^ 0xFF = ~A
A ^ (~A) = 0xFF
A ^ A = 0x00
对于两数:A和B,有:
都是位运算,不分前后关系。
A ^ B ^ A = A ^ A ^ B = (A ^ A) ^ B = 0x00 ^ B = B
集合相信都学过:位运算可以和集合论中的概念来表示。并,交,补,相信大家都不陌生了。
| 为并,&为交,~为补。
以上,总结一下,发现总结确实可以加深很多。