0

我正在尝试创建一个通过存储整数的有序数组来优化布尔数组的类,这些整数的位可以访问各个位以查看它们是打开还是关闭。对我知道那个

std::vector<bool> 

做这样的事情,但我正在尝试自己实现,以供练习。

例如,一个无符号短整数是 16 位,所以我可以将 100 个布尔值打包成一个由 7 个无符号短整数组成的数组,其中最后一个元素充当填充。

当我对此进行测试时,我发现某些地方已经出了问题,可能与我的 print() 函数有关。在 main 中,您可以看到我创建了一个包含 32 个布尔值的 BitPack 对象,它将存储在一个由 2 个无符号短整数组成的数组中,并且我已经验证确实如此。但是,我的打印功能不起作用,因为它给了我以下输出,而不是应该的 32 个零。

0000000000000000

我已经多次查看我的打印功能,但无法找出问题所在。很抱歉,当我在这里复制我的代码时丢失了任何缩进。非常感谢任何帮助。

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

typedef unsigned short int usi;

class BitPack { 

public: 
    BitPack(int);
    ~BitPack(); 
    bool getVal(int);
    int getSize();
    void setVal(int, bool);
    void print();

private:
    const static int USI_BITS = sizeof(usi)*CHAR_BIT; 
    usi* _booArr;
    int _booArrLen;
    int _numBoos;

};

BitPack::BitPack(int sz) { 
     assert (sz > 0);           
      _numBoos = sz;
  _booArrLen = _numBoos/USI_BITS+(_numBoos % USI_BITS ? 1 : 0);
  _booArr = new usi[_booArrLen];
  for (int i = 0; i < _booArrLen; ++i)
     _booArr[i] = 0;
} 

BitPack::~BitPack() {
    delete[] _booArr;
}

bool BitPack::getVal(int indx) {
    assert (indx > 0);  
    usi bA_indx_val = _booArr[indx/USI_BITS];
    bA_indx_val >>= (bA_indx_val % USI_BITS);
    return (bA_indx_val % 2 ? true : false);
}

int BitPack::getSize() { 
    return (_numBoos);
}

void BitPack::setVal(int indx, bool valset) { 
    assert (indx > 0);
    bool curval = getVal(indx);
    if ((curval == true) && (valset == false)) {
        _booArr[indx/USI_BITS] += (1 << (indx % USI_BITS));
    } else if ((curval == true) && (valset == false)) {
        _booArr[indx/USI_BITS] -= (1 << (indx % USI_BITS));
    }
} 

void BitPack::print() { 
    int i = 0;
    usi thisval;
    while (i < _booArrLen - 1) {
        thisval = _booArr[i];
        for (int j = 0; j < USI_BITS; ++j) {
            std::cout << (thisval % 2 ? '1' : '0');
            thisval >>= 1;
        }
        i++;
    }
    thisval = _booArr[i];
    for (int j = 0; j < _numBoos % USI_BITS; ++j) { 
        std::cout << (thisval % 2 ? '1' : '0');
        thisval >>= 1;
    }
}

int main (int argc, char* const argv[]) {

    BitPack bp(32);
    bp.print();

    return 0;
}
4

2 回答 2

0

我发现并纠正了一些错误:

bool BitPack::getVal(int indx) {
    assert (indx >= 0);                 // Use >=
    usi bA_indx_val = _booArr[indx/USI_BITS];
    bA_indx_val >>= (indx % USI_BITS);  // use indx here instead of bA_indx_val
    return ((bA_indx_val & 1) ? true : false);
}

BitPack::setVal() 也有一些问题:

void BitPack::setVal(int indx, bool valset) {
    assert (indx >= 0);           // Use >= 
    bool curval = getVal(indx);
    if ((curval == true) && (valset == false)) {
        _booArr[indx/USI_BITS] &= ~(1 << (indx % USI_BITS));  // Use bitwise operators
    } else if ((curval == false) && (valset == true)) {       // corrected this expression
        _booArr[indx/USI_BITS] |= (1 << (indx % USI_BITS));   // Use bitwise operators
    }
}

使用 -= 和 += 来操作位比 &= 和 |= 位运算符要正确得多。

它似乎适用于一些基本测试,但我没有验证它是否适用于所有位位置。

于 2013-11-10T06:25:28.740 回答
0

'这可以在 VB.NET 中完成。

'我有一个包含 20 个 Shorts 或 Integer 的数组,我想将它们传入和传出一个包含 320 个项(16 位)的布尔数组

'我正在使用复选框数组,但可以使用 Treeview 或其他布尔对象数组

'MyCheckbox(320) 被声明为 Public

'---------------------------------------------------- ------------------------- '--------- -------------------------------------------------- ------ Private Sub ReadData() '读取整数 (0-65535)

Dim Intx As Int16
Dim Bit As Int16
 
For Intx = 0 To 19
        For Bit = 0 To 15
            MyCheckbox(Bit + (Intx * 16)).Checked = CBool(MyDataTable.Data(Intx) And CInt(2 ^ Bit))
        Next Bit
    Next Intx
End Sub   
   

'---------------------------------------------------- ------------------------- '--------- -------------------------------------------------- ------

Private Sub WriteData() ' 如果已更改,则将相同的数据写回 Short (-32768-32767)

Dim Shorty As Short Dim Bit As Short

For Shorty = 0 To 19 ' Array of 20 Type Integer or Short
     For Bit = 0 To 15 ' 16 Bits
            If MyCheckbox(Bit + (Shorty * 16)).Checked Then
                MyDataTable.Data(Shorty) = (MyDataTable.Data(Shorty) Or CShort(1S << Bit))
                Else
                  MyDataTable.Data(Shorty) = (MyDataTable.Data(Shorty) And Not (CShort(1S << Bit)))
             End If           
Next
    Next
End Sub

'---------------------------------------------------- ------------------------- '--------- -------------------------------------------------- ------

于 2022-02-11T12:44:36.993 回答