程序中位运算的运用

简介:

一、权限设置

第一步, 先建立一个枚举表示所有的权限管理操作,接下来是权限的运算等。

  常用的位运算主要有与(&), 或(|)和非(~), 比如:

  1 & 0 = 0, 1 | 0 = 1, ~1 = 0

  在设计权限时, 我们可以把权限管理操作转换为C#位运算来处理.

  第一步, 先建立一个枚举表示所有的权限管理操作:

  [Flags]

  public enum Permissions

  {

  Insert = 1,

  Delete = 2,

  Update = 4,

  Query = 8

  }

  [Flags]表示该枚举可以支持C#位运算, 而枚举的每一项值, 我们用2的n次方来赋值, 这样表示成二进制时刚好是1 = 0001, 2 = 0010, 4 = 0100, 8 = 1000等, 每一位表示一种权限, 1表示有该权限, 0表示没有.

  接下来是权限的运算:

  1. 权限的加法, 使用与运算来实现. 我们知道, 0001 | 0100 = 0101, 这样就表示同时具有第一位和第三位的权限管理了, 枚举表示为:

  Permissions per = Permissions.Insert | Permissions.Update

  2. 权限的减法, 使用与运算+非运算来实现, 如上面要去掉Insert权限, 操作为:

  Permissions per &= ~Permissions.Insert即是 0101 & ~0001 = 0101 & 1110 = 0100

  3. 权限的判断, 使用与运算, 当判断用一用户是否具有该操作权限时, 要把用户的的权限与操作权限进行与运算, 如果得到的结果仍是操作权限管理, 则表示用户具有该权限:

  Permissions per = Permissions.Insert | Permissions.Update;

  if(per & PermissionsPermissions.Insert = Permissions.Insert)

  {

  //有操作权限

  }

  比较过程为 0101 & 0001 = 0001, 0001的0位用与C#位运算把其它位都置成0, 变成只比较1的这一位.

 

二、月份的设置

有时候需要在一个数据表里面保存十二个月份中某几个月份的标志

这时候可以使用1个字段来代替12个字段,就要运用到十进制来保存月份的记录,然后通过位运算来进行读取和判断

public enum MonthMask

  {

  month1= 1,

  month2= 2,

  month3= 4,

  month4= 8

……

  }

 

一个字段保存12个月份的标示,高效,简单

同样的道理,二进制可以用来保存多个标示符,可以运用到很多方面

 

三、论坛帖子

在SQL Server ,采用1,2,4,8,16.....等用数字标识的状态字段可以进行累加,对存在的几种状态进行组合,从而可形成各种组合状态

例如:一条记录该字段原来的数字是,2,如我们想加上4,则可以用

update t_User set iFlag = iFlag | 4 where UserID = 1

(iFlag 为该字段名)

例2:在加上4之后我们想去掉4怎么办呢,可以这样实现

update t_User set iFlag = iFlag ^4 where UserID = 1

这样就又把4从该记录中去掉了.

如果我们想选择所有为2的记录该怎么做呢,可以这样实现

select * from t_User where iFlag &2 = 2

SQL中的位运算不但可以取出各种值,而且我们可以对他对数据进行排序

举例如下,新闻列表中的一个字段标识为

1:置顶

2:不置顶

4:推荐

8:不推荐

该字段的值可以为这4种状态的组合,如果我们根据一定条件想把所有置顶的放在前面该如何做呢

select * from t_News order by iFlag & 1 desc

这样我们就把所有置顶的贴子排在前面,当然这里可以加上一定的Where 条件,在Where 里也可可以加一定的位运算,

关于位运算可以查阅相应的SQL 帮助

下面来讲一讲C#中的枚举位运算

这里我们定义一个枚举

[Flags]
enum UserFlag
{
a = 1,
b = 2,
c = 4,
d = 8,
e = 16,
f = 32
}

 

在代码里加上如下处理

protected void Page_Load(object sender, EventArgs e)
{

if (!IsPostBack)
{

string strSQL = "select * from v_User where iFlag & @iFlag = @iFlag";

//SqlParameter parm = new SqlParameter("@iFlag",SqlDbType.Int,4);
//parm.Value = UserFlag.a | UserFlag.b ;
SqlConnection con = new SqlConnection("server=.;database=Sinvan_TexDB;User Id=sa;pwd=123;");

SqlCommand comm = new SqlCommand(strSQL, con);

comm.Parameters.Add("@iFlag", SqlDbType.Int, 4).Value = UserFlag.a | UserFlag.b;

SqlDataAdapter adp = new SqlDataAdapter(comm);
DataTable dTable = new DataTable();
adp.Fill(dTable);


UserFlag userFlag = (UserFlag)Enum.Parse(typeof(UserFlag), dTable.Rows[0][11].ToString());
 

}
}

 

进行处理之后userFlag就是数据库中存在的各种组合

我们同样可对其进行一定的位运算处理

如我们想加上 UserFlag.c 可进行如下操作

userFlag = userFlag | Userflag.c

如想去掉UserFlag.c 可进行如下操作

userFlag = userFlag ^ UserFlag.c

如我们要判断是该标识中是否存在c可进行如下操作

(userFlag & UserFlag.c) == UserFlag.c



本文转自linzheng 51CTO博客,原文链接:http://blog.51cto.com/linzheng/1081597

相关文章
|
3月前
玩转位运算
玩转位运算
|
6月前
|
存储 Java
一篇搞定位运算(&、|、^、~、>>、<<、>>>)
我们最了解的就是十进制 , 除了十进制 , 还有二进制 , 六进制 , 八进制等等 , 由于位运算操作就是二进制 , 所以我们主要来说一下二进制 , 十进制的个位有(0~9)这几个数字 , 而二进制也相同 , 二进制的个位上只有0和1
32 0
|
8月前
|
算法 Java 编译器
第 13 天_位运算
第 13 天_位运算
59 0
|
9月前
|
算法
位运算能做什么
位运算能做什么
38 0
|
9月前
|
存储
位运算及A+B
位运算及A+B
|
10月前
|
存储 Java 程序员
“高端”的位运算
大家好,我是王有志。原计划迭代作为预备知识的收尾,不过在解2的幂和4的幂时,想到关于数字2的问题可以通过位运算去解决,因此补充了关于位运算的内容。
60 1
位运算的解析与运用
位运算的解析与运用
62 0
|
存储
移位运算、位运算、逻辑运算相关知识点及笔试题
移位运算、位运算、逻辑运算相关知识点及笔试题
204 0
移位运算、位运算、逻辑运算相关知识点及笔试题

热门文章

最新文章