位运算的妙用

来源:互联网 发布:dedecms中js如何使用 编辑:程序博客网 时间:2024/06/06 13:24

先说一下位运算的简单用法

1. 按位与 &

用途:清零,取一个数中的某些指定位,保留一个数中的某些指定位

2. 按位或 |

用途:将一个数的某些位指定为1

3. 按位异或 ^

用途:交换两个数

a=a^b; b=a^b; a=a^b

让我们看看这三条语句执行后的结果:

第一条a=a^b,所以第二条b=a^b=(a^b)^b=a^(b^b)=a^0=a,现在b的值是a

第三条a=a^b=(a^b)^a=b^(a^a)=b^0=b,现在a的值是b啦!完成互换!

4. 取反 ~

5. 左移 << , 右移 >>

位运算最大的优点就是操作简单,效率高。可以看如下例子:

1. 假设一个变量有如下属性{输入,输出,类型,长度(如果是数组的话;如果不是数组那么长度为0)},试问你如何表示这个变量呢?

用一个结构体来表示这些属性?甚至用一个类?。。。嘿嘿,事实上只用一个int型就OK了。一个int型有32位,足够了,我们可以任意设置标志位的位置。比如第32位表示输出,第31位表示输入,第17-24位表示类型,第1-16位表示长度。好啦,如果一个变量是输入(则32位是1),不是输出(则31位是0),类型是char(假设char对应1,那么17-24位是00000001),长度是5,下面的int type可以表示全部信息:

int type=(1<<31)|(1<<16) |5

以后可以通过按位与来取得任何信息,比如要取得长度,可以type & 0x0000FFFF

2. 棋盘的表示:

选择什么样的数据结构可以表示一个棋盘呢?二维数组肯定是大多数人冒出的第一想法,不过二维数组操作起来不并像想象那么简单。如果棋盘是8*8的,实际上我们可以用一个64位长度的变量来表示棋盘。每一位对应棋盘的每一格。对于传统的只有黑白子的游戏,可以使用两个变量:第一个64位变量记录黑子的棋盘情况(如果棋盘的[i][j]位置有黑子,则第(i-1)*8+j位是1,否则是0),同样,第二个64位变量记录白子的棋盘情况。这样,判断棋子、吃子、翻转子等操作就可以用与、或、异或等位运算很方便高效地实现了。有些棋类游戏存在基本的“棋局”模式,而这个模式则可以用另一个变量记录。这个变量作为一个模版,可以与原棋盘变量进行位运算来判断原棋盘是否出现了这样一个特定的棋局模式。而如果用数组来表示棋盘,这些操作则会复杂许多。

而对于象棋这样的棋类游戏,棋子的种类并不是只有一黑一白的,应该要维持多个棋盘变量,具体可以参考以下链接:

http://www.elephantbase.net/computer/struct_bitboard.htm

0 0