Lind.DDD.Manager里的3,7,15,31,63,127,255,511,1023,2047
進制
我(wo)是(shi)一個(ge)程(cheng)序猿,我(wo)喜(xi)歡簡單(dan)(dan)的數字(zi)(zi),十進制(zhi)(zhi)(zhi)如何(he),數字(zi)(zi)太(tai)多,有10種(zhong)數字(zi)(zi)組成,但由于它廣(guang)為人知,所有使(shi)用(yong)最為廣(guang)泛,人們(men)的慣性(xing)思維培養了(le)十進制(zhi)(zhi)(zhi),并(bing)說(shuo)它是(shi)最容易被計算的數字(zi)(zi),事(shi)實(shi)上,在計算機里,最簡單(dan)(dan)的進制(zhi)(zhi)(zhi)是(shi)當然是(shi)二進制(zhi)(zhi)(zhi),原因最為直接(jie),因為它只有兩種(zhong)數字(zi)(zi),0和1。
二進制里的最簡單的運算
不(bu)是(shi)(shi)加,也不(bu)是(shi)(shi)減(jian),而是(shi)(shi)位(wei)移(yi),即將數(shu)(shu)字(zi)水平向(xiang)(xiang)左或(huo)者向(xiang)(xiang)右進行(xing)移(yi)動(dong),在數(shu)(shu)學里(li)的(de)(de)(de)實際(ji)意(yi)義就是(shi)(shi)乘以2和除(chu)以2,對(dui)于(yu)每種高級程序設計來(lai)說都有(you)自(zi)己(ji)的(de)(de)(de)位(wei)運(yun)算符(fu),大多部都使用(yong)<<和>>來(lai)表(biao)示,對(dui)于(yu)位(wei)運(yun)算,它有(you)自(zi)己(ji)的(de)(de)(de)實際(ji)意(yi)義,對(dui)于(yu)自(zi)然數(shu)(shu)字(zi)2來(lai)說,它的(de)(de)(de)實際(ji)意(yi)義是(shi)(shi)什么呢?讓(rang)我們來(lai)一起看一下。
自然數據2的奧秘
十進制:2,對應二(er)進制的10
位移運算的結果
對上面(mian)的(de)結果,我們(men)可(ke)以(yi)看到2的(de)位移運(yun)(yun)算剛好是2的(de)N次冪,這個確(que)實很有(you)意(yi)思(si),但(dan)還不(bu)是最有(you)意(yi)思(si)的(de),對于(yu)數字來說(shuo)還有(you)一(yi)些位運(yun)(yun)算,下面(mian)我們(men)來看一(yi)下圖示(shi)。
我們(men)看(kan)一下2的(de)指數,分別是(shi)1到10在,而它的(de)冪我們(men)是(shi)否很熟悉,這在計算機設置(zhi)里經常可(ke)以看(kan)到,你(ni)的(de)內存,硬盤,U盤,顯卡上的(de)存儲(chu)存量應該都有它們(men)的(de)身影,我們(men)可(ke)以試著把這些冪進行按位取或,看(kan)一下結果
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
實際意義
這(zhe)(zhe)個有點像楊輝三(san)角的(de)(de)(de)東西在(zai)我們平時開(kai)發時經常會用到,因為對(dui)于這(zhe)(zhe)些(xie)結果都只有唯一(yi)的(de)(de)(de)結合,我們如果把(ba)每(mei)位(wei)代表(biao)一(yi)種權(quan)限(xian),那么(me),可以把(ba)這(zhe)(zhe)些(xie)結果代表(biao)這(zhe)(zhe)些(xie)權(quan)限(xian)的(de)(de)(de)組合,這(zhe)(zhe)確實(shi)很有意思,而(er)在(zai)這(zhe)(zhe)些(xie)組合里,我們也(ye)可以查找哪些(xie)元素(權(quan)限(xian))不在(zai)某個結果之內,這(zhe)(zhe)些(xie)都可以使用位(wei)移運算實(shi)現(xian)。
/// <summary> /// 從(cong)位集合中找到空位 /// </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; }
大叔曾經也對(dui)一些聚(ju)(ju)合(he)運算進(jin)(jin)行(xing)了擴展,對(dui)sum,count這些聚(ju)(ju)集來說,位運算是不適合(he)的(de),如果我們希望(wang)對(dui)一個集合(he)進(jin)(jin)行(xing)按運求(qiu)和(或),如何去實(shi)現了,.net基礎(chu)類庫沒有這種方式,所以,大叔對(dui)它(ta)進(jin)(jin)行(xing)了擴展,代碼如下
/// <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; }
對于上面的(de)(de)位移運算來(lai)說,它們的(de)(de)實現意義在大叔的(de)(de)權限(xian)體系里(li)得到(dao)了完(wan)美的(de)(de)體現,我們可(ke)以(yi)看一下(xia)數據表的(de)(de)設(she)計,使用Flag來(lai)設(she)計授權按(an)鈕,即每(mei)種按(an)鈕都有唯一的(de)(de)位標識,而它們可(ke)以(yi)相互組(zu)合!
授權按鈕組件的結果
對于(yu)角色授權時,你可(ke)以將多種按鈕組合授權,而使用一個字(zi)段來(lai)存儲位運算(suan)的結果即可(ke),無論從效率還是操作上,都比拼字(zi)符串和關(guan)系表來(lai)的更(geng)容易!
本代(dai)碼選自《Lind.DDD.Manager》相關代(dai)碼和程序的截(jie)圖!
感謝各位的閱讀!