Bit Array Set Range

Started by
1 comment, last by Adam_42 14 years, 1 month ago
I'm writing my own Bit Array class and so far everything's going good. The problem I'm coming across is finding a more elegant/efficient way to set a range of bits to either off or on. Right now in my class I loop through my range of bits in a 'for' loop to set each bit individually, but I think there may be a much better/efficient way to set the bits that I haven't though of. Thanks. Here is my implementation:

#define SET_BIT(a, b)	(((char*)a)[(b)>>3] |= (1 << ((b)&7)))
#define CLEAR_BIT(a, b)	(((char*)a)[(b)>>3] &= ~(1 << ((b)&7)))
#define GET_BIT(a, b)	((((char*)a)[(b)>>3] >> ((b)&7)) & 1)
#define ARRAY_BYTE_SIZE 4

class BitArray
{
	public:
		BitArray(unsigned int bufferSize);
		~BitArray();
		bool GetBit(unsigned int index);
		void SetBit(unsigned int index, bool setValue);
		void SetRange(unsigned int startIndex, unsigned int endIndex, bool setValue);

		char *GetBitBuffer(void){return m_BitBuffer;}
		
		void AllocateMemory(unsigned int bufferSize);
		void FreeMemory(char * bitBuffer);

	private:
		unsigned int m_ArrayLength;
		char *m_BitBuffer;
};


//Purpose:
//Ctor for the bit array.
//Input:
//buffersize - size of bit array in bytes
//Returns:
//N/A
BitArray::BitArray(unsigned int bufferSize)
{
	m_ArrayLength = bufferSize << 3;
	AllocateMemory(bufferSize);
}

//Purpose:
//Gets a specific bit at the given index, and
//returns its binary value.
//Input:
//index - the index of the bit within the bit array
//Returns:
//The given bits binary value, 0/false or 1/true.
bool BitArray::GetBit(unsigned int index)
{
	if(index < 0 || index > m_ArrayLength-1)
	{
		cout << "Index " << index <<  " Out of Bounds!!!" << endl;
		return false;
	}

	return GET_BIT(m_BitBuffer, index);
}

//Purpose:
//Sets a specific bit on or off at the given index.
//Input:
//index - the index of the bit within the bit array
//setValue - the value to set the bit to, 0/false and 1/true
//Returns:
//N/A
void BitArray::SetBit(unsigned int index, bool setValue)
{
	if(index < 0 || index > m_ArrayLength-1)
	{
		cout << "Index " << index <<  " Out of Bounds!!!" << endl;
		return;
	}

	if(setValue)
	{
		SET_BIT(m_BitBuffer, index);
	}
	else
	{
		CLEAR_BIT(m_BitBuffer, index);
	}
}

//Purpose:
//Sets a range of bits from the given indices, inclusively,
//to either on or off
//Input:
//startIndex - the starting range index of the bit within the bit array
//			   that will be set to either 0/false or 1/true.
//endIndex - the ending range index of the bit within the bit array
//			   that will be set to either 0/false or 1/true.
//setValue - the value to set the range of bits to, 0/false and 1/true
//Returns:
//N/A
void BitArray::SetRange(unsigned int startIndex, unsigned int endIndex, bool setValue)
{
	if(startIndex < 0 || startIndex > m_ArrayLength-1)
	{
		cout << "Index " << startIndex <<  " Out of Bounds!!!" << endl;
		return;
	}
	if(endIndex < 0 || endIndex > m_ArrayLength-1)
	{
		cout << "Index " << endIndex <<  " Out of Bounds!!!" << endl;
		return;
	}
	if(startIndex >= endIndex)
	{
		cout << "Incorrect Range!!!" << endl;
		return;
	}

	if(setValue)
	{
		for(unsigned int i = startIndex; i <= endIndex; i++)
		{
			SET_BIT(m_BitBuffer, i);
		}
	}
	else
	{
		for(unsigned int i = startIndex; i <= endIndex; i++)
		{
			CLEAR_BIT(m_BitBuffer, i);
		}
	}
}

//Purpose:
//To allocate memory for the bit array's bit buffer 
//and set them to off by default.
//Input:
//bufferSize - the size of the bit array in bytes
//Returns:
//N/A
void BitArray::AllocateMemory(unsigned int bufferSize)
{
	m_BitBuffer = (char*)malloc(bufferSize * sizeof(char));
	memset(m_BitBuffer, 0, sizeof(char) * bufferSize);
}

//Purpose:
//To free memory when the object is detroyed.
//Input:
//bitBuffer - the chunk of memory the bit array holds
//			  that needs to be released
//Returns:
//N/A
void BitArray::FreeMemory(char * bitBuffer)
{
	free(bitBuffer);
	cout << "Bit Array Memory Freed!!!" << endl;
}

//Purpose:
//Dtor for the bit array.
//Input:
//N/A
//Returns:
//N/A
BitArray::~BitArray()
{
	FreeMemory(m_BitBuffer);
}

Alabama Man!!!
Advertisement
Crosspost

To set n bits from bit i, do (2n - 1) << i
[TheUnbeliever]
What you probably want to do is use memset to handle whole bytes, which should be much quicker for large ranges. Something like this untested code (note that all the index variables will have to be signed for this to work, and I'm assuming m_BitBuffer is an array of chars):

// Work out the first and last whole byte we can process with memset()int startByte = (startIndex + 7) / 8;int endByte = (endIndex+1) / 8;// Handle the odd bits before the main lotfor(int i = startIndex; i <= min((startByte * 8)-1, endIndex); i++){	SET_BIT(m_BitBuffer, i);}// Clear out the whole bytesif (endByte > startByte) memset(&m_BitBuffer[startByte], 0xff, endByte - startByte);// Handle any trailing bitsfor(int i = endByte * 8; i <= endIndex; i++){	SET_BIT(m_BitBuffer, i);}

This topic is closed to new replies.

Advertisement