zoukankan      html  css  js  c++  java
  • 程序中位运算的运用

    一、权限设置

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

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

      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

  • 相关阅读:
    use imagination
    tar
    简单抓取安居客房产数据,并保存到Oracle数据库
    svn的安装(整合apache、ldap)包括错误解决post commit FS processing had error
    SVN安装中遇到的问题
    Linux环境源码编译安装SVN
    [转]SVN安装问题The Apache Portable Runtime (APR) library cannot be found
    深入浅出数据分析-脑图
    Python3.5在Windows 7下连接ORACLE数据库
    Python3.5之TuShare
  • 原文地址:https://www.cnblogs.com/linzheng/p/1855166.html
Copyright © 2011-2022 走看看