在8K字节的内存空间内,如何存unsigned short类型数据?
一般做法:
定义一个数组:unsigned short arrNormal[4096];
这样做,最多只能存4K个unsigned short数据。
利用位图法:
定义一个数组:unsigned char arrBit[8192];
这样做,能存8K*8=64K个unsigned short数据。
写数据元素:计算待写入数据在arrBit存放的字节位置和位位置(字节0~8191,位0~7)
比如写1234,字节序:1234/8 = 154; 位序:1234 & 0b111 = 2,那么1234放在arrBit的下标154字节处,把该字节的2号位(0~7)置为1
字节位置:int nBytePos = 1234/8 = 154;
位位置: int nBitPos = 1234 & 7 = 2;
//把数组的154字节的2位置为1
unsigned short val = 1<<nBitPos;
arrBit[nBytePos] = arrBit[nBytePos] | val; //写入1234得到arrBit[154]=0b00000100
此时再写入1236,
字节位置:int nBytePos = 1236/8 = 154;
位位置: int nBitPos = 1236 & 7 = 4
.// /把数组的154字节的4位置为1
val = 1<<nBitPos;
arrBit[nBytePos] = arrBit[nBytePos] | val; //再写入1236得到arrBit[154]=0b00010100
读数据元素:按位读取arrBit,取得位为1的字节位置和位位置。元素值为8* nBytePos + nBitPos
for (i=0; i<8192; i++)
{
for (j=0; j<8; j++)
{
if (arrBit[i] & (1<<j))
{
cout << "arrBit:" << i << " " << j << " " << 8*i+j << endl;
}
}
}
会输出:
arrBit:154 2 1234
arrBit:154 4 1236
删除元素:计算待删除元素的字节位置和位位置:arrBit[nBytePos] &= ~(1<< nBitPos);
比如删除1234:arrBit[154] &= ~(1<<2);
位图法的缺点:
1.可读性差
2.位图存储的元素个数虽然比一般做法多,但是存储的元素大小受限于存储空间的大小。
位图存储性质:存储的元素个数等于元素的最大值。
比如,1K字节内存,能存储8K个值大小上限为8K的元素。(元素值上限为8K,这个局限性很大!)
比如,要存储值为65535的数,就必须要65535/8=8K字节的内存。要就导致了位图法根本不适合存unsigned int类型的数(大约需要2^32/8=5亿字节的内存)。
3.位图对有符号类型数据的存储,需要2位来表示一个有符号元素。这会让位图能存储的元素个数,元素值大小上限减半。
比如8K字节内存空间存储short类型数据只能存8K*4=32K个,元素值大小范围为-32K~32K。
综上所诉:位图法的适用范围很特殊。