回到目錄 進位 我是一個程式猿,我喜歡簡單的數字,十進位如何,數字太多,有10種數字組成,但由於它廣為人知,所有使用最為廣泛,人們的慣性思維培養了十進位,並說它是最容易被計算的數字,事實上,在電腦里,最簡單的進位是當然是二進位,原因最為直接,因為它只有兩種數字,0和1。 二進位里的最簡單的運算 不 ...
進位
我是一個程式猿,我喜歡簡單的數字,十進位如何,數字太多,有10種數字組成,但由於它廣為人知,所有使用最為廣泛,人們的慣性思維培養了十進位,並說它是最容易被計算的數字,事實上,在電腦里,最簡單的進位是當然是二進位,原因最為直接,因為它只有兩種數字,0和1。
二進位里的最簡單的運算
不是加,也不是減,而是位移,即將數字水平向左或者向右進行移動,在數學里的實際意義就是乘以2和除以2,對於每種高級程式設計來說都有自己的位運算符,大多部都使用<<和>>來表示,對於位運算,它有自己的實際意義,對於自然數字2來說,它的實際意義是什麼呢?讓我們來一起看一下。
自然數據2的奧秘
十進位:2,對應二進位的10
位移運算的結果
對上面的結果,我們可以看到2的位移運算剛好是2的N次冪,這個確實很有意思,但還不是最有意思的,對於數字來說還有一些位運算,下麵我們來看一下圖示。
我們看一下2的指數,分別是1到10在,而它的冪我們是否很熟悉,這在電腦設置里經常可以看到,你的記憶體,硬碟,U盤,顯卡上的存儲存量應該都有它們的身影,我們可以試著把這些冪進行按位取或,看一下結果
1 | 2=3
1 | 2 | 4=7
1 | 2 | 4 | 8=15
1 | 2 | 4 | 8 | 16 =31
1 | 2 | 4 | 8 | 16 | 32=127
實際意義
這個有點像楊輝三角的東西在我們平時開發時經常會用到,因為對於這些結果都只有唯一的結合,我們如果把每位代表一種許可權,那麼,可以把這些結果代表這些許可權的組合,這確實很有意思,而在這些組合里,我們也可以查找哪些元素(許可權)不在某個結果之內,這些都可以使用位移運算實現。
/// <summary> /// 從位集合中找到空位 /// </summary> /// <param name="max"></param> /// <param name="he"></param> /// <returns></returns> long GetValidNumber(long he) { for (long i = 1; i < he; i = i << 1) { if ((he & i) != i) return i; } return 0; }
大叔曾經也對一些聚合運算進行了擴展,對sum,count這些聚集來說,位運算是不適合的,如果我們希望對一個集合進行按運求和(或),如何去實現了,.net基礎類庫沒有這種方式,所以,大叔對它進行了擴展,代碼如下
/// <summary> /// 按或進行位運算 /// 作者:倉儲大叔 /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="source"></param> /// <param name="selector"></param> /// <returns></returns> public static long BinaryOr<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector) { long result = 0; foreach (var item in source) { result |= selector(item); } return result; }
對於上面的位移運算來說,它們的實現意義在大叔的許可權體系裡得到了完美的體現,我們可以看一下數據表的設計,使用Flag來設計授權按鈕,即每種按鈕都有唯一的位標識,而它們可以相互組合!
授權按鈕組件的結果
對於角色授權時,你可以將多種按鈕組合授權,而使用一個欄位來存儲位運算的結果即可,無論從效率還是操作上,都比拼字元串和關係表來的更容易!