天天看點

C++ BitSet位操作符bitset 操作自己編寫一個BitSetReferences

文章目錄

  • 位操作符
  • bitset 操作
  • 自己編寫一個BitSet
    • BitSet.h
    • b.h
    • a.cpp
    • 輸出
  • References

還是溫習C++

位操作符

操作符 功能 用法
~ 按位非 ~expr
<< 左移 expr1 << expr2
>> 右移 expr1 >> expr2
& 按位與 expr1 & expr2
^ 按位異或 expr1 ^ expr2
| 按位或 expr1 | expr2
&= 按位與指派 expr1 &= expr2
^= 按位異或指派 expr1 ^= expr2
|= 按位或指派 expr1 |=expr2
  • ~

    位反轉:0轉1,0轉1
00001000 // a
   ~ 00001000 // ~a
-------------
     11110111 // result = ~a
           
  • <<

    所有位整體往左移動,超過 左邊最高位 的舍棄,右邊補0位
11110111 // a
  << 11110111 // a << 1
-------------
     11101110 // result = a << 1
           
  • >>

    所有位整體往右移動,超過右邊最低為舍棄,左邊補符号位 或是 0,這由具體實作定義。
// 左側補上符号位的情況
     11101110 // a
  >> 11101110 // a >> 1
-------------
     11110111 // result = a >> 1
           
// 左側補上0位的情況
     11101110 // a
  >> 11101110 // a >> 1
-------------
     01110111 // result = a >> 1
           
  • &

    兩個相同位數的資料 同位 上的位資料 都為1,則 結果 為1,否則為0
01110111 // a
   & 11101110 // b
-------------
     01100110 // result = a & b
           
  • ^

    兩個相同位數的資料 同位 上的位資料 隻有一個1,則 結果 為1,否則為0
11110111 // a
   ^ 01110111 // b
-------------
     10000000 // result = a ^ b
           
  • |

    兩個相同位數的資料 同位 上的位資料 隻要有一個1,則 結果 為1,否則為0
11001100 // a
   | 10000101 // b
-------------
     11001101 // result = a | b
           
  • &=, ^=, |=

    與前面的功能相同,隻不過多了一個對左值指派

bitset 操作

操作 功能 用法
test(pos) pos 位是否為1? a.test(4)
any() 任意為是否為1? a.any()
none() 是否沒有位為1? a.none()
count() 值是1的位的個數 a.count()
size() 位元素的個數 a.size()
[pos] 通路 pos 位 a[4]
flip() 翻轉所有的位 a.flip()
set() 将所有位置1 a.set()
set(pos) 将 pos 位置1 a.set(4)
reset() 将所有位置0 a.reset()
reset(pos) 将 pos 位置0 a.reset(4)

自己編寫一個BitSet

提供類似以上的所有功能。

BitSet.h

/* BitSet.h - jave.lin 2020.05.15 為了學習用,我們就不用<bitset>了,改而自己寫個 BitSet */
#pragma once

#include <iostream>
#include <string>
#include <assert.h>

namespace BS {

//
// === statement start ===
//

#define __BS32_F(n) uint32_t f##n : 1;
#define __BS64_F(n) uint64_t f##n : 1;

struct _Bit32 {
    __BS32_F( 1)__BS32_F( 2)__BS32_F( 3)__BS32_F( 4)
    __BS32_F( 5)__BS32_F( 6)__BS32_F( 7)__BS32_F( 8)
    __BS32_F( 9)__BS32_F(10)__BS32_F(11)__BS32_F(12)
    __BS32_F(13)__BS32_F(14)__BS32_F(15)__BS32_F(16)
    __BS32_F(17)__BS32_F(18)__BS32_F(19)__BS32_F(20)
    __BS32_F(21)__BS32_F(22)__BS32_F(23)__BS32_F(24)
    __BS32_F(25)__BS32_F(26)__BS32_F(27)__BS32_F(28)
    __BS32_F(29)__BS32_F(30)__BS32_F(31)__BS32_F(32)
};
struct _Bit64 {
    __BS64_F( 1)__BS64_F( 2)__BS64_F( 3)__BS64_F( 4)
    __BS64_F( 5)__BS64_F( 6)__BS64_F( 7)__BS64_F( 8)
    __BS64_F( 9)__BS64_F(10)__BS64_F(11)__BS64_F(12)
    __BS64_F(13)__BS64_F(14)__BS64_F(15)__BS64_F(16)
    __BS64_F(17)__BS64_F(18)__BS64_F(19)__BS64_F(20)
    __BS64_F(21)__BS64_F(22)__BS64_F(23)__BS64_F(24)
    __BS64_F(25)__BS64_F(26)__BS64_F(27)__BS64_F(28)
    __BS64_F(29)__BS64_F(30)__BS64_F(31)__BS64_F(32)
    __BS64_F(33)__BS64_F(34)__BS64_F(35)__BS64_F(36)
    __BS64_F(37)__BS64_F(38)__BS64_F(39)__BS64_F(40)
    __BS64_F(41)__BS64_F(42)__BS64_F(43)__BS64_F(44)
    __BS64_F(45)__BS64_F(46)__BS64_F(47)__BS64_F(48)
    __BS64_F(49)__BS64_F(50)__BS64_F(51)__BS64_F(52)
    __BS64_F(53)__BS64_F(54)__BS64_F(55)__BS64_F(56)
    __BS64_F(57)__BS64_F(58)__BS64_F(59)__BS64_F(60)
    __BS64_F(61)__BS64_F(62)__BS64_F(63)__BS64_F(64)
};

using pos_t = unsigned char;
using count_t = size_t;

template<class BSType, class BSValueType>
union _UBitSet {
public:
    using valueType = BSValueType;

    BSValueType value;
    BSType fs;
    _UBitSet()                                          : value((BSValueType)0) {}
    _UBitSet(const int &a)                              : value((BSValueType)a) {}
    _UBitSet(const unsigned short &a)                   : value((BSValueType)a) {}
    _UBitSet(const long &a)                             : value((BSValueType)a) {}
    _UBitSet(const long long &a)                        : value((BSValueType)a) {}
    _UBitSet(const BSValueType a)                       : value(a) {}
    _UBitSet(const _UBitSet<BSType, BSValueType> &a)    : value(a.value) {}
    _UBitSet(const std::string &bitStr);
    _UBitSet(const char *bitChars);
    void getStr(std::string &str);
    void getStr(char *str);
    void getStrFormat(std::string &str, int interval = 8); // format隻支援可變長的string,char *需要封裝處理很麻煩
    // pos 位是否為1?注意pos從1開始,不是索引
    inline bool test(const pos_t pos) const;
    // 任意為是否為1?
    inline bool any() const;
    // 是否沒有位為1?
    inline bool none() const;
    // 值是1的位的個數
    const count_t count() const;
    // 位元素的個數
    inline const size_t size() const;
    // 通路 pos 位
    inline BSValueType operator[](pos_t pos);
    // 翻轉所有的位
    inline void flip();
    // 将所有位置1
    inline void set();
    // 将 pos 位置1
    inline void set(const pos_t pos);
    // 将所有位置0
    inline void reset();
    // 将 pos 位置0
    inline void reset(const pos_t pos);

    inline _UBitSet<BSType, BSValueType> &operator=(std::string &str);
    // 其他的operator沒必要重載了,因為就一個value,外部設定操作即可
};

using BitSet_32         = union _UBitSet<struct _Bit32, uint32_t>;
using BitSet_64         = union _UBitSet<struct _Bit64, uint64_t>;

template<typename T>
void __convertBits(T &bs, std::string &str);

template<typename T>
void __getStr(T bs, std::string &str);

template<typename T>
void __getStr(T bs, char *str);

template<typename T>
void __getStrFormat(T bs, std::string &ret, int interval = 8);

template <class _Elem, class _Traits>
std::basic_ostream<_Elem,_Traits>& operator<<(std::basic_ostream<_Elem,_Traits>& i, BitSet_32& c);

template <class _Elem, class _Traits>
std::basic_ostream<_Elem,_Traits>& operator<<(std::basic_ostream<_Elem,_Traits>& i, BitSet_64& c);

//
// === statement end ===
//

//
// === definition start ===
//

template<class BSType, class BSValueType>
_UBitSet<BSType, BSValueType>::_UBitSet(const std::string &bitStr) : value((BSValueType)0) {
    __convertBits<BSValueType>(this->value, bitStr);
}

template<class BSType, class BSValueType>
_UBitSet<BSType, BSValueType>::_UBitSet(const char *bitChars) : value((BSValueType)0) {
    std::string str(bitChars);
    __convertBits<BSValueType>(this->value, str);
}

template<typename T>
void __convertBits(T &bs, std::string &str) {
    size_t size = sizeof(T) * 8;
    size = size < str.size() ? size : str.size();
    int i = str.size() - size;
    i = i < 0 ? 0 : i;
    bs = 0;
    for (; i < size; ++i) {
        // printf("%c ", str[i]);
        if (str[i] == '1') {
            bs |= (((T)1) << (size - 1 - i));
        } else {
            if (str[i] == '0') {
                bs &= ~(((T)1) << (size - 1 - i));
            } else {
                // throw ("bitset_str_invalidated_exception");
            }
        }
    }
    // printf("\n");
}

template<class BSType, class BSValueType>
void _UBitSet<BSType, BSValueType>::getStr(std::string &str) {
    __getStr(this->value, str);
}

template<class BSType, class BSValueType>
void _UBitSet<BSType, BSValueType>::getStr(char *str) {
    __getStr(this->value, str);
}

template<class BSType, class BSValueType>
void _UBitSet<BSType, BSValueType>::getStrFormat(std::string &str, int interval) {
    __getStrFormat<BSValueType>(this->value, str, interval);
}

template<class BSType, class BSValueType>
inline bool _UBitSet<BSType, BSValueType>::test(const pos_t pos) const {
    assert (pos > 0);
    return ((this->value >> (pos - 1)) & (1));
    // return (((this->value) & (((BSValueType)1) << (pos - 1))));
}
template<class BSType, class BSValueType>
inline bool _UBitSet<BSType, BSValueType>::any() const {
    return this->value != 0;
}
template<class BSType, class BSValueType>
inline bool _UBitSet<BSType, BSValueType>::none() const {
    return this->value == 0;
}

template<class BSType, class BSValueType>
const count_t _UBitSet<BSType, BSValueType>::count() const {
    size_t size = sizeof(BSValueType) * 8;
    count_t count = 0;
    BSValueType v = this->value;
    for (size_t i = 0; i < size; i++) {
        ((v >> i) & (1)) && ++count;
    }
    return count;
}

template<class BSType, class BSValueType>
inline const size_t _UBitSet<BSType, BSValueType>::size() const {
    return sizeof(BSValueType) * 8;
}

template<class BSType, class BSValueType>
inline BSValueType _UBitSet<BSType, BSValueType>::operator[](pos_t pos) {
    return (((this->value) & (((BSValueType)1) << (pos - 1))));
}

template<class BSType, class BSValueType>
inline void _UBitSet<BSType, BSValueType>::flip() {
    this->value = ~(this->value);
}

template<class BSType, class BSValueType>
inline void _UBitSet<BSType, BSValueType>::set() {
    this->value = -1;
}

template<class BSType, class BSValueType>
inline void _UBitSet<BSType, BSValueType>::set(const pos_t pos) {
    this->value |= (((BSValueType)1) << (pos - 1));
}

template<class BSType, class BSValueType>
inline void _UBitSet<BSType, BSValueType>::reset() {
    this->value = 0;
}

template<class BSType, class BSValueType>
inline void _UBitSet<BSType, BSValueType>::reset(const pos_t pos) {
    this->value &= ~(((BSValueType)1) << (pos - 1));
}

template<class BSType, class BSValueType>
inline _UBitSet<BSType, BSValueType> & _UBitSet<BSType, BSValueType>::operator=(std::string &str) {
    __convertBits<BSValueType>(this->value, str);
    return *this;
}

template<typename T> // T : uint32_t or uint64_t
void __getStr(T bs, std::string &ret) {
    size_t size = sizeof(T) * 8;
    size_t sizem1 = size - 1;
    ret.resize(size);
    for (size_t i = 0; i < size; i++) {
        ret[sizem1 - i] = ( ((bs >> i) & (1)) ? '1' : '0' );
    }
}

template<typename T>// T : uint32_t or uint64_t
void __getStr(T bs, char *str) {
    size_t size = sizeof(T) * 8;
    size_t sizem1 = size - 1;
    for (size_t i = 0; i < size; i++) {
        str[sizem1 - i] = ( ((bs >> i) & (1)) ? '1' : '0' );
    }
    str[size] = '\0';
}

template<typename T>// T : uint32_t or uint64_t
void __getStrFormat(T value, std::string &str, int interval) {
    int size = sizeof(T) * 8;
    // printf("int size = %d\n", sizeof(T));
    int addSize = size / interval;              // 需要添加多少個分隔符
    if (size % interval == 0) addSize -= 1;     // 如果分隔N份是偶數的大小就減1
    int newSize = size + addSize;               // 加上分隔符後的大小
    if (str.size() < newSize) str.resize(newSize); // 調整string大小
    int newSizeM1 = newSize - 1;                // newSizeM1 = newSize Minus One
    int idx = 0;                                // 插入分隔符的計數索引
    int splitterCount = 0;                      // 統計插入了幾個分隔符
    for (size_t i = 0; i < newSize; i++) {
        str[newSizeM1 - i - splitterCount] = ( ((value >> i) & (1)) ? '1' : '0' );
        if (++idx / interval != 0) {
            idx = 0;
            ++splitterCount;
            if ((i + splitterCount) < newSize) {
                str[newSizeM1 - i - splitterCount] = ',';
                // printf("insert at : %d\n", newSizeM1 - i);
            } else {
                return; // 到尾部了
            }
        }
    }
} // void __getStrFormat

template <class _Elem, class _Traits>
std::basic_ostream<_Elem,_Traits>& operator<<(std::basic_ostream<_Elem,_Traits>& i, BitSet_32& c) {
    std::string str;
    __getStrFormat<uint32_t>(c.value, str);
    i << str;
    return i;
}

template <class _Elem, class _Traits>
std::basic_ostream<_Elem,_Traits>& operator<<(std::basic_ostream<_Elem,_Traits>& i, BitSet_64& c) {
    std::string str;
    __getStrFormat<uint64_t>(c.value, str);
    i << str;
    return i;
}


//
// === definition end ===
//

} // namespace BS
           

b.h

/* b.h - jave.lin */
#pragma once
#include "BitSet.h" // 順便測試重複include "BitSet.h",#pragma once有無作用
           

a.cpp

/* a.cpp - jave.lin */
#include <iostream>
#include <typeinfo>
#include <assert.h>
// #include <bitset>    // 不用内置的,我們為了學習,自己寫個類似bitset的功能
#include "b.h"          // 測試重複#include "BitSet.h",看看#pragma once有無效果
#include "BitSet.h"     // 自己寫個BitSet

void testMyBitSet() {

    std::string str1;

    printf("Now Testing Type : %s\n", typeid(BS::BitSet_32).name());
    printf("sizeof(%s) : %d\n", typeid(BS::BitSet_32).name(), sizeof(BS::BitSet_32));

    BS::BitSet_32 myBitSet32;
    std::cout << "myBitSet32.size() = " << myBitSet32.size() << '\n';
    myBitSet32.fs.f1 = 1;
    std::cout << "after : myBitSet32.fs.f1 = 1;" << '\n';
    printf("myBitSet32.fs.f1 = %d\n", myBitSet32.fs.f1);
    printf("myBitSet32.value = %d\n", myBitSet32.value);

    myBitSet32.fs.f2 = 1;
    std::cout << "after : myBitSet32.fs.f2 = 1;" << '\n';
    printf("myBitSet32.fs.f2 = %d\n", myBitSet32.fs.f2);
    printf("myBitSet32.value = %d\n", myBitSet32.value);

    myBitSet32.value = 1 | 1 << 1;
    std::cout << "after : myBitSet32.value = 1 | 1 << 1;" << '\n';
    printf("myBitSet32.value = %d\n", myBitSet32.value);

    myBitSet32.getStr(str1);
    std::cout << "after : myBitSet32.getStr(str1);" << '\n';
    printf("str1 = %s\n", str1.c_str());
    std::cout << "str1 : " << str1 << "\n";

    char str3[65];
    myBitSet32.getStr(str3);
    std::cout << "after : char str3[65];myBitSet32.getStr(str2);" << '\n';
    printf("str2 = %s\n", str3);
    std::cout << "str2 : " << str3 << "\n";

    myBitSet32.getStrFormat(str1);
    std::cout << "after : myBitSet32.getStrFormat(str3);" << '\n';
    printf("str3 = %s\n", str1.c_str());
    std::cout << "str3 : " << str1 << "\n";

    // myBitSet32.value = 4096;
    myBitSet32.value = 4095;
    std::cout << "after : myBitSet32.value = 4095;" << '\n';
    std::cout << "myBitSet32 = " << myBitSet32 << '\n';
    //          f1  f2  f3  f4  f5   f6
    myBitSet32.value = 1 | 2 | 4 | 8 | 16 | 32;
    std::cout << "after : myBitSet32.value = 1 | 2 | 4 | 8 | 16 | 32;" << '\n';
    std::cout << "myBitSet32 = " << myBitSet32 << '\n';

    myBitSet32.value = 0;
    myBitSet32.fs.f1 = 1;
    myBitSet32.fs.f2 = 1;
    myBitSet32.fs.f3 = 1;
    myBitSet32.fs.f4 = 1;
    myBitSet32.fs.f5 = 1;
    myBitSet32.fs.f6 = 1;
    myBitSet32.fs.f7 = 1;
    myBitSet32.fs.f8 = 1;
    myBitSet32.fs.f9 = 1;
    myBitSet32.fs.f32 = 1;
    std::cout << "after : myBitSet32.fs.f1~f9,f32 = 1;" << '\n';
    std::cout << "str4.value = " << myBitSet32.value << '\n';
    std::cout << "myBitSet32 = " << myBitSet32 << '\n';

    printf("\nNow Testing Type : %s\n", typeid(BS::BitSet_64).name());
    printf("sizeof(%s) : %d\n", typeid(BS::BitSet_64).name(), sizeof(BS::BitSet_64));

    BS::BitSet_64 myBitSet64;
    std::cout << "myBitSet64.size() = " << myBitSet64.size() << '\n';

    myBitSet64.value = myBitSet32.value;
    std::cout << "after myBitSet64.value = myBitSet32.value;" << '\n';
    std::cout << "myBitSet64.value = " << myBitSet64.value << '\n';
    std::cout << "myBitSet64 = " << myBitSet64 << '\n';

    myBitSet64.fs.f33 = 1;
    myBitSet64.fs.f38 = 1;
    myBitSet64.fs.f45 = 1;
    myBitSet64.fs.f60 = 1;
    myBitSet64.fs.f62 = 1;
    std::cout << "after : myBitSet64.fs.f33,f38,f45,f60,f62 = 1;" << '\n';
    std::cout << "myBitSet64 = " << myBitSet64 << '\n';

    std::cout << "\nBitSet operation func test\n";

    std::cout << "myBitSet64 = " << myBitSet64 << '\n';
    std::cout << "myBitSet64.test(33) = " << myBitSet64.test(33) << '\n';
    std::cout << "myBitSet64.test(34) = " << myBitSet64.test(34) << '\n';
    std::cout << "myBitSet64.fs.f33   = " << myBitSet64.fs.f33 << '\n';
    std::cout << "myBitSet64.fs.f34   = " << myBitSet64.fs.f34 << '\n';
    
    BS::BitSet_64::valueType srcV = myBitSet64.value;
    myBitSet64.value = 0;
    std::cout << "after : myBitSet64.value = 0;\n";
    std::cout << "myBitSet64 = " << myBitSet64 << '\n';
    std::cout << "myBitSet64.any()      = " << myBitSet64.any() << '\n';
    std::cout << "myBitSet64.none()     = " << myBitSet64.none() << '\n';
    std::cout << "myBitSet64.count()    = " << myBitSet64.count() << '\n';
    myBitSet64.value = srcV;
    std::cout << "after : myBitSet64.value = srcV;\n";
    std::cout << "myBitSet64 = " << myBitSet64 << '\n';
    std::cout << "myBitSet64.any()      = " << myBitSet64.any() << '\n';
    std::cout << "myBitSet64.none()     = " << myBitSet64.none() << '\n';
    std::cout << "myBitSet64.count()    = " << myBitSet64.count() << '\n';

    BS::__getStrFormat<BS::BitSet_64::valueType>(myBitSet64[32], str1);
    std::cout << "after : BS::__getStrFormat<BS::BitSet_64::valueType>(myBitSet64[32], str1);\n";
    std::cout << "myBitSet64[32]        = " << myBitSet64[32] << '\n';
    std::cout << "myBitSet64[32] = str1 = " << str1 << '\n';
    myBitSet64.value = myBitSet64[32];
    std::cout << "after : myBitSet64.value = myBitSet64[32];\n";
    std::cout << "myBitSet64            = " << myBitSet64 << '\n';
    myBitSet64.flip();
    std::cout << "after : myBitSet64.flip();\n";
    std::cout << "myBitSet64            = " << myBitSet64 << '\n';
    myBitSet64.flip();
    std::cout << "after : myBitSet64.flip(); again\n";
    std::cout << "myBitSet64            = " << myBitSet64 << '\n';
    myBitSet64.set();
    std::cout << "after : myBitSet64.set();\n";
    std::cout << "myBitSet64            = " << myBitSet64 << '\n';

    myBitSet64.reset();
    std::cout << "after : myBitSet64.reset();\n";
    std::cout << "myBitSet64            = " << myBitSet64 << '\n';

    myBitSet64.set(18);myBitSet64.fs.f28 = 1;
    std::cout << "after : myBitSet64.set(18);myBitSet64.fs.f28 = 1;\n";
    std::cout << "myBitSet64            = " << myBitSet64 << '\n';

    myBitSet64.reset(18);myBitSet64.fs.f28 = 0;
    std::cout << "after : myBitSet64.reset(18);myBitSet64.fs.f28 = 0\n";
    std::cout << "myBitSet64            = " << myBitSet64 << '\n';

    BS::BitSet_64 bs_from_str("11001011");
    std::cout << "after BS::BitSet_64 bs_from_str(\"11001011\");\n";
    std::cout << "bs_from_str           = " << bs_from_str << '\n';
    std::string bitStr = "10101010101010101";
    bs_from_str = bitStr;
    std::cout << "after std::string bitStr  = \"10101010101010101\";bs_from_str = bitStr;\n";
    std::cout << "bs_from_str               = " << bs_from_str << '\n';
    bitStr = "110001";
    bs_from_str = bitStr;
    std::cout << "after bitSt           = \"110001\";bs_from_str = bitStr;\n";
    std::cout << "bs_from_str           = " << bs_from_str << '\n';
}

int main() {
    auto default_v = 1; // default_v 是整數 預設為int
    printf("typeid(default_v).name() : %s\n", typeid(default_v).name());
    printf("sizeof(1 << 8):%d\n", sizeof(1 << 8));

    unsigned long long_v = 1;
    printf("long_v:%d\n", long_v);
    long_v <<= 8;
    printf("long_v <<= 8; long_v:%d\n", long_v);
    printf("typeid(long_v).name() : %s\n", typeid(long_v).name());
    printf("sizeof(long_v):%d\n", sizeof(long_v));

    unsigned long long llong_v = 1;
    printf("llong_v:%d\n", llong_v);
    llong_v <<= 8;
    printf("llong_v <<= 8; llong_v:%d\n", llong_v);
    printf("typeid(llong_v).name() : %s\n", typeid(llong_v).name());
    printf("sizeof(llong_v):%d\n", sizeof(llong_v));
    printf("sizeof(llong_v << 8):%d\n", sizeof(llong_v << 8)); // longlong 64bit超過32bits的都會保持64bits

    unsigned short us_v = 1;
    printf("us_v:%d\n", us_v);
    us_v <<= 8;
    printf("us_v <<= 8; us_v:%d\n", us_v);
    printf("typeid(us_v).name() : %s\n", typeid(us_v).name());
    printf("sizeof(us_v):%d\n", sizeof(us_v));
    printf("sizeof(us_v << 8):%d\n", sizeof(us_v << 8)); // unsigned short 原本是16位的,2bytes,但是位移後的值變成4bytes 32bits對齊了

    // 那麼我們開始使用自己封裝的一個BitSet

    printf("\n ====== BitSet testing start ======\n");

    testMyBitSet();

    printf("\n ====== BitSet testing end ======\n");

    // #ifdef __TEST
    // printf("\n ====== has define __TEST Macro in tasks.json's compile args  ======\n");
    // #endif

    // #ifdef __TEST1
    // printf("\n ====== has define __TEST1 Macro in c_cpp_extension.json's compilerArgs  ======\n");
    // #endif
    
    // #ifdef __TEST2
    // printf("\n ====== has define __TEST2 Macro in c_cpp_extension.json's defines  ======\n");
    // #endif

    return 0;
}
           

輸出

typeid(default_v).name() : i
sizeof(1 << 8):4
long_v:1
long_v <<= 8; long_v:256
typeid(long_v).name() : m
sizeof(long_v):4
llong_v:1
llong_v <<= 8; llong_v:256
typeid(llong_v).name() : y
sizeof(llong_v):8
sizeof(llong_v << 8):8
us_v:1
us_v <<= 8; us_v:256
typeid(us_v).name() : t
sizeof(us_v):2
sizeof(us_v << 8):4
 ====== BitSet testing start ======
Now Testing Type : N2BS8_UBitSetINS_6_Bit32EjEE
sizeof(N2BS8_UBitSetINS_6_Bit32EjEE) : 4
myBitSet32.size() = 32
after : myBitSet32.fs.f1 = 1;
myBitSet32.fs.f1 = 1
myBitSet32.value = 1
after : myBitSet32.fs.f2 = 1;
myBitSet32.fs.f2 = 1
myBitSet32.value = 3
after : myBitSet32.value = 1 | 1 << 1;
myBitSet32.value = 3
after : myBitSet32.getStr(str1);
str1 = 00000000000000000000000000000011
str1 : 00000000000000000000000000000011
after : char str3[65];myBitSet32.getStr(str2);
str2 = 00000000000000000000000000000011
str2 : 00000000000000000000000000000011
after : myBitSet32.getStrFormat(str3);
str3 = 00000000,00000000,00000000,00000011
str3 : 00000000,00000000,00000000,00000011
after : myBitSet32.value = 4095;
myBitSet32 = 00000000,00000000,00001111,11111111
after : myBitSet32.value = 1 | 2 | 4 | 8 | 16 | 32;
myBitSet32 = 00000000,00000000,00000000,00111111
after : myBitSet32.fs.f1~f9,f32 = 1;
str4.value = 2147484159
myBitSet32 = 10000000,00000000,00000001,11111111
Now Testing Type : N2BS8_UBitSetINS_6_Bit64EyEE
sizeof(N2BS8_UBitSetINS_6_Bit64EyEE) : 8
myBitSet64.size() = 64
after myBitSet64.value = myBitSet32.value;
myBitSet64.value = 2147484159
myBitSet64 = 00000000,00000000,00000000,00000000,10000000,00000000,00000001,11111111
after : myBitSet64.fs.f33,f38,f45,f60,f62 = 1;
myBitSet64 = 00101000,00000000,00010000,00100001,10000000,00000000,00000001,11111111
BitSet operation func test
myBitSet64 = 00101000,00000000,00010000,00100001,10000000,00000000,00000001,11111111
myBitSet64.test(33) = 1
myBitSet64.test(34) = 0
myBitSet64.fs.f33   = 1
myBitSet64.fs.f34   = 0
after : myBitSet64.value = 0;
myBitSet64 = 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000
myBitSet64.any()      = 0
myBitSet64.none()     = 1
myBitSet64.count()    = 0
after : myBitSet64.value = srcV;
myBitSet64 = 00101000,00000000,00010000,00100001,10000000,00000000,00000001,11111111
myBitSet64.any()      = 1
myBitSet64.none()     = 0
myBitSet64.count()    = 15
after : BS::__getStrFormat<BS::BitSet_64::valueType>(myBitSet64[32], str1);
myBitSet64[32]        = 2147483648
myBitSet64[32] = str1 = 00000000,00000000,00000000,00000000,10000000,00000000,00000000,00000000
after : myBitSet64.value = myBitSet64[32];
myBitSet64            = 00000000,00000000,00000000,00000000,10000000,00000000,00000000,00000000
after : myBitSet64.flip();
myBitSet64            = 11111111,11111111,11111111,11111111,01111111,11111111,11111111,11111111
after : myBitSet64.flip(); again
myBitSet64            = 00000000,00000000,00000000,00000000,10000000,00000000,00000000,00000000
after : myBitSet64.set();
myBitSet64            = 11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111
after : myBitSet64.reset();
myBitSet64            = 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000
after : myBitSet64.set(18);myBitSet64.fs.f28 = 1;
myBitSet64            = 00000000,00000000,00000000,00000000,00001000,00000010,00000000,00000000
after : myBitSet64.reset(18);myBitSet64.fs.f28 = 0
myBitSet64            = 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000
after BS::BitSet_64 bs_from_str("11001011");
bs_from_str           = 00000000,00000000,00000000,00000000,00000000,00000000,00000000,11001011
after std::string bitStr  = "10101010101010101";bs_from_str = bitStr;
bs_from_str               = 00000000,00000000,00000000,00000000,00000000,00000001,01010101,01010101
after bitSt           = "110001";bs_from_str = bitStr;
bs_from_str           = 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00110001
 ====== BitSet testing end ======
           

References

  • C++ Primer 第三版 中文版.pdf提取碼:czse - 139 頁 - bitset