I am writing my own version of a bitset, because I need one that has dynamic size. Therefore I can't use std::bitset
, which is apparently fixed in size.
I now needed to write a method for bitshifting. I found several solutions on how to do bitshifting on arrays or vectors, but none of them was comprehensible to me.
For example the accepted answer in this question:
Bitwise shifting array of char's
No explanation on where the constants 0x07
3
and 5
come from. So I wrote my own method that made sense to me and works. But it has a runtime of O(n), where n is the number of bits in the bitset. And I assume this could be reduced to O(m) where m is the number of ints (or whatever basic type is used to store the bit pattern) in the bitset. Anpther issue is that my method is not in-place and requires e temporary instance of my bitset class.
My code is not really relevant to the question, but it maybe gives it some context.
My method looks like this:
friend BitEncoder& operator<<(BitEncoder& src, int shift)
{
BitEncoder tmp;
for (int i = 0; i < src.size(); i++)
{
if (src[i])
{
tmp(i+shift);
}
}
src = tmp;
return src;
}
The rest of the class with the irrelevant methods cut out is this:
/**
* @brief BitEncoder is a dynamic bitset.
*/
class BitEncoder
{
public:
/**
* @brief basic constructor
*/
BitEncoder() {}
/**
* @brief alias for setter function
*/
void operator()(int i)
{
set(i);
}
/**
* @brief read-only index operator
*/
bool operator[](int i)
{
unsigned int j = i/(sizeof(int)*8);
if (j >= bits.size())
{
throw 0;
}
return (bits[j] & (1 << i));
}
/**
* @brief sets the ith bit
*/
void set(int i)
{
// compute the cell in which the index falls
unsigned int j = i/(sizeof(int)*8);
// if the cell is larger than the highest index add as many new cells as
// necessary
if (!(j < bits.size()))
{
bits.resize(j+1);
}
// if the bit is already set, return
if (bits[j] & (1 << i)) return;
// set the bit
bits[j] += (1 << i);
}
unsigned size(){return bits.size()*sizeof(int)*8;}
friend BitEncoder& operator<<(BitEncoder& src, int shift)
{
BitEncoder tmp;
for (int i = 0; i < src.size(); i++)
{
if (src[i])
{
tmp(i+shift);
}
}
src = tmp;
return src;
}
private:
std::vector<int> bits;
};
Ok, so much for the context. I know this question is kind of a duplicate, but as I said, the answers I found so far are not understandable to me.
Could somebody explain in a more comprehensive manner on the example of a std::vector, like I used in my class to store the bit pattern, ow to perform a bitshift on a vector / array?