将8个布尔人保存到1个字节中

Saving 8 booleans into 1 byte

本文关键字:1个 字节 保存 8个 布尔人      更新时间:2023-10-16

我正在编码一个程序,写入一个大型布尔区域(通常约为512*512 bool变量)。这将极大地利用以一种明智的方式保存它,我正在考虑将它们保存8乘8,将这8个布尔人编码为形式的一个字节:

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

,但我不确定如何处理此转换,尽管我知道要编写和读取一个字节。

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

欢呼。

编辑:

在Sean的帮助下(谢谢!),我设法进一步又有了一些,但它仍然不起作用,保存和阅读后对数据进行了测试,告诉我它已被损坏(如未正确重建和因此,在写作,阅读或两者兼有的某个地方与初始数据不完全相同...

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

这是写作行:

    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>对象,对我来说比操纵char中的位要清楚得多。稍后我可能会使用工作代码更新我的帖子。我仍然关心效率,与您认为的效率要快得多吗?

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

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

您可以在这样的循环中将bool s编码为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;
}