做爲一名程序員,寫技術型博客還是很有必要的,那就從這裏開始吧。
看了兩天的bitset源碼,覺得理解下面幾點後,看源碼應該不難了。
bitset存儲二進制數,是以arr[ulong] 這樣的一個數組方式存儲的。
每一個ulong存儲32位的bit。
所以當你聲明一個bitset<n>時,就得計算需要多少個ulong來存儲這些bit
__BITSET_WORDS就是這樣作用的。
#define __BITSET_WORDS(__n) \
((__n) < 1 ? 1 : ((__n) + __BITS_PER_WORD - 1)/__BITS_PER_WORD)
__BITS_PER_WORD:計算每個ulong佔用多少位Bit。
#define __BITS_PER_WORD (CHAR_BIT*sizeof(unsigned long))
_S_bit_count:這個靜態數組,保存着256個char,每個char有多少位1
如7 = 0111,即_S_bit_count[7] = 3
template<bool __dummy>
struct _Bit_count {
static unsigned char _S_bit_count[256];
};
_S_first_one:這個靜態數組,保存着每個char裏,第一個bit 1,後面有多少位0
如:6 = 0110 _S_first_one[6] = 1;
如:8 = 1000 _S_first_one[8] = 3;
template<bool __dummy>
struct _First_one {
static unsigned char _S_first_one[256];
};
_S_whichword: 獲取二進制位__pos,在數組_M_w中下標是幾。
_S_whichbyte: 獲取在word中,第幾個char。
_S_whichbit: 獲取在word中,第幾個bit。
(重要,也比較難理解)_S_maskbit:
取__pos位,在當前ulong中的掩碼。
如: _S_whichword(__pos) = 5,_S_whichbit(__pos) = 3
即:_S_maskbit(__pos) = 00...00 0100
數組5下的word,第3個值的掩碼1,
爲接口set,reset,flip等使用
static _WordT _S_maskbit( size_t __pos )
{ return (static_cast<_WordT>(1)) << _S_whichbit(__pos); }
_M_do_sanitize:使__val高_Extrabits位,置0。
template <size_t _Extrabits> struct _Sanitize {
static void _M_do_sanitize(unsigned long& __val)
// (~static_cast<unsigned long>(0)) : 1111 1111...
// (~static_cast<unsigned long>(0)) << _Extrabits : 1111...000
// ~((~static_cast<unsigned long>(0)) << _Extrabits): 000...111
{ __val &= ~((~static_cast<unsigned long>(0)) << _Extrabits); }
};
帶有詳細註釋的bitset源碼文件