将8个布尔值保存为1个字节

时间:2014-01-23 12:22:01

标签: c++ serialization save

我正在编写一个程序,写入一个大的bool区域(通常大约512 * 512个bool变量)。它会很好地以智能的方式保存它,我正在考虑将它们保存8乘8,将这8个布尔值编码为一个字节:

byte = bit0 * boolean0 | ... | bit7 * boolean7

但是我不知道如何处理这种转换,尽管我知道要逐字节地写入和读取文件。

我正在使用C ++,我没有CS的背景但是这似乎接近于序列化的主题,尽管我在这个主题上搜索的所有内容对我来说都是不清楚的。它已经实现了,还是有一个非常简单的方法来实现它? (我的意思是节省尽可能多的CPU时间,我的程序将为每个实例编写并打开数百万个这样的文件)

干杯。

编辑:

在肖恩的帮助下(谢谢你!)我设法得到了进一步但它仍然无法正常工作,保存和阅读后的数据测试告诉我它被破坏(如未正确重建和所以与写作,阅读或两者都在某处的初始数据不一样......

我的代码可能会有所帮助。

以下是写作行:

    typedef char byte;
    ofstream ofile("OUTPUT_FILE");
    for(int i=0;i<N/8;i++){
    byte encoded = 0;
    for(int j=0; j<8; j++){
        byte bit = (byte)(tab[(i*8+j)/h][(i*8+j)%h]==1);
        encoded = (encoded << 1) | bit;
        }           
    ofile << encoded;
    }

和阅读线:

for(int i=0;i<N/8;i++){ //N is the total number of entries I have in my final array
    temp = ifile.get(); //reading the byte in a char
    for(int j=0; j<8; j++){ // trying to read each bits in there
        if(((temp >> j) & 1) ? '1' : '0' ){
            tab[(i*8+j)/h][(i*8+j)%h]=1;
            }
        else{
            tab[(i*8+j)/h][(i*8+j)%h]=-1; //my programs manipulates +1 (TRUE) and -1 (FALSE) making most of the operations easier
            }
        }
    }
ifile.close();

EDIT2:

我终于设法使用bitset&lt; 8&gt;对象,对我来说比操纵char中的位更清楚。我可能会稍后用我的工作代码更新我的帖子。我仍然关注效率,你觉得使用它比使用bitset要快得多吗?

2 个答案:

答案 0 :(得分:3)

如果您不需要在运行时确定位数组的大小,可以使用std :: bitset

http://en.cppreference.com/w/cpp/utility/bitset

答案 1 :(得分:1)

您可以像这样在循环中将bool编码为int

bool flags[8];

// populate flags from somewhere

byte encoded=0;

for(int i=0; i<8; i++)
{
  byte bit = (byte)flags[i];
  encoded = (encoded << 1) | bit;
}

该代码使用这样一个事实,即bool为一个数字生成true为1,false为o。

或者你可以展开它:

byte encoded = 0;
encoded |= ((byte)flags[0]) << 7;
encoded |= ((byte)flags[1]) << 6;
encoded |= ((byte)flags[2]) << 5;
encoded |= ((byte)flags[3]) << 4;
encoded |= ((byte)flags[4]) << 3;
encoded |= ((byte)flags[5]) << 2;
encoded |= ((byte)flags[6]) << 1;
encoded |= ((byte)flags[7]);

要将字节转换回标志数组,您可以执行以下操作:

bool flags[8];
byte encoded= /* some value */

for(int i=0, i<8; i++)
{
  bool flag=(bool)(encoded & 1);
  flags[7-i]=flag;
  encoded>>=1;
}