二進制狀態碼

我們知道計算機中數據都是用二進制數存儲。二進制數是一系列0和1的組合,長整型64位,最短的字節型也有8位。其中每一位0和1都可以看做一種狀態的開和關,所以就有了這樣的一種狀態碼存儲方式:把同一對象的多種狀態按位組合到一個整數中。

例如我們最最常見的 *nix 文件權限:

第9位 第8位 第7位 第6位 第5位 第4位 第3位 第2位 第1位 第0位
是否目錄 所有者讀權限 所有者寫權限 所有者執行權限 組讀權限 組寫權限 組執行權限 其餘用戶讀權限 其餘用戶寫權限 其餘用戶執行權限
0 1 1 1 1 0 1 1 0 1

那麼這一組狀態在程序中表示爲:0b0111101101,即八進制的 0o755,十進制的 493

二進制狀態碼存儲的主要好處是節省存儲空間,相對於鍵值對(對象)存儲而言可讀性較差(當然文件權限這種另說)。這種存儲方式僅適用於“一個對象有多種狀態,每種狀態僅有兩種情況”這一情形,請不要對一種狀態多種情況的情形使用二進制狀態碼存儲方式,更不要出現十進制的 0 1 10 這種狀態碼,很蠢。。。

使用位運算操作狀態碼

基於這種存儲方式,也衍生了一些操作狀態碼的方式:

判斷第 x 位狀態是否開啓(x 以 0 開始,下同):

status & (1 << x) == 0

打開第 x 位

status |= 1 << x

關閉第 x 位

status &= ~(1 << x)

編程語言支持

某些編程語言提供了對二進制狀態碼的一些原生支持。C/C++ 提供了 位域,以及專門的模板庫 bitset 用於簡化位運算操作。C# 則提供了 Flags 特性標記某個枚舉被視作位域

另外很重要一點,JavaScript 雖然也支持位運算,但由於 JavaScript 中的 number 類型都是雙精度浮點數,在做位運算時會先將數值截斷至 32 位長度。例如很著名的數字轉整數bug:10000000000 | 0 => 1410065408。所以注意如果後端返回二進制狀態碼讓前端判斷,確保後端使用 uint32_t 存儲

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章