天天看點

程式中位運算的運用

一、權限設定

第一步, 先建立一個枚舉表示所有的權限管理操作,接下來是權限的運算等。

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

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

  第一步, 先建立一個枚舉表示所有的權限管理操作:

  [Flags]

  public enum Permissions

  {

  Insert = 1,

  Delete = 2,

  Update = 4,

  Query = 8

  }

  接下來是權限的運算:

  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