2014-09-18 69 views
1

我的官方问题是:“是否有一种干净的方式来使用数据类型来”编码和压缩“数据,而不是使用凌乱的位掩码。”希望能够在压缩的情况下节省空间,并且我想使用本地数据类型,结构和数组来提高位掩码的可读性。我精通从我的程序集背景掩盖位,但我正在学习C++和OOP。我们可以通过使用单独的位将这么多信息存储在32位寄存器中,并且我觉得我正在尝试回到低级环境,同时具有C++代码的可读性。我可以使用像bool这样的数据类型来压缩数据,同时提高可读性吗?

我试图节省一些空间,因为我正在处理巨大的资源需求。我仍然在学习更多关于C++如何处理bool数据类型的知识。我意识到内存是存储在字节块中而不是单个的位。我相信bool通常使用一个字节并以某种方式被屏蔽。在我的脑海中,我可以在一个字节中使用8 bool值。

如果我malloc在C++中的一个数组的2 bool元素。它分配两个字节还是只分配一个字节?

示例:我们将使用DNA作为示例,因为它可以编码为两位来表示A,C,G和T.如果我用一个名为DNA_Base的两个bool的数组构造一个结构体,那么我将创建一个数组其中20个。

struct DNA_Base{ bool Bit_1; bool Bit_2; }; 
DNA_Base DNA_Sequence[7] = {false}; 
cout << sizeof(DNA_Base)<<sizeof(DNA_Sequence)<<endl; 
//Yields a 2 and a 14. 
//I would like this to say 1 and 2. 

在我的例子中,我还将展示DNA序列长度为20个碱基,需要40位编码的情况。 GATTACA最多只能占用2个字节?我想另外一个问题就是“如何让C++以更可读的方式为我掩饰”或者我应该创建自己的数据类型和类,并使用类和运算符重载实现位掩码。

+0

'bool'实际上使用了一个完整的字节。除非使用按位联合或“std :: bitset”,否则不能真正处理内存中的一位。 – 2014-09-18 19:18:25

+1

查看'std :: bitset'或错误名为'std :: vector '的方法来创建用于存储部分字节元素的伪容器。 – Deduplicator 2014-09-18 19:19:48

+0

它可能不是空间最优的,但使用'enum'或'enum class:char'来表示每个基地可能是最可读和最有效的表示。位字段通常应该避免。 – Jason 2014-09-18 19:38:20

回答

2

不是你想要完全什么,但你可以使用bitfield

struct DNA_Base 
{ 
    unsigned char Bit_1 : 1; 
    unsigned char Bit_2 : 1; 
}; 
DNA_Base DNA_Sequence[7]; 

所以sizeof(DNA_Base) == 1sizeof(DNA_Sequence) == 7

所以,你必须收拾DNA_Base以避免失去地方与填充,东西如:

struct DNA_Base_4 
{ 
    unsigned char base1 : 2; // may have value 0 1 2 or 3 
    unsigned char base2 : 2; 
    unsigned char base3 : 2; 
    unsigned char base4 : 2; 
}; 

所以sizeof(DNA_Base_4) == 1

std::bitset是另一种选择,但你必须自己做解释工作。

0

布尔数组将是N元素x sizeof(布尔)。

如果您的目标是节省寄存器中的空间,请不要打扰,因为使用字节大小对于处理器来说实际上比使用单个字节更有效,编译器更愿意使用无论如何,所以在结构/类中,bool通常会扩展为32位或64位本机字。

现在,如果您想节省磁盘空间或RAM中的空间,因为需要存储大量的布尔,请继续,但不会在所有情况下节省空间,除非您实际打包结构,并且在某些体系结构中,打包也会对性能产生影响,因为CPU必须执行未对齐或逐字节访问。

另一方面,位掩码(或位域)是高性能,高效且尽可能密集的,并使用单个按位操作。我会看看提供位域的抽象数据类型之一。

标准库的bitset http://www.cplusplus.com/reference/bitset/bitset/可以只要你想要的。

Boost也有我确定的东西。

0

除非你在4位机器上,否则最终结果将是使用位算术。无论你是否明确地做到这一点,让编译器通过位字段来完成它,或者使用一个容器,将会进行位操作。

我建议如下:

  • 利用现有的压缩库。
  • 使用比你自己的其他人更易读或易于理解的方法 。
  • 使用最有成效的方法(谈论开发 时间)。
  • 使用您将注入最少量缺陷的方法。

编辑1:
收件每个方法作为单独的功能。
告诉编译器为每个函数生成汇编语言。 比较每个函数的汇编语言。

我的看法是,他们会非常相似,足够浪费时间讨论他们是不值得的。

0

不能对位直接操作,但可以提供的最小单位为多个数据存储处理给你,并定义

enum class DNAx4 : uint8_t { 
    AAAA = 0x00, AAAC = 0x01, AAAG = 0x02, AAAT = 0x03, 
    // .... And the rest of them 
    AAAA = 0xFC, AAAC = 0xFD, AAAG = 0xFE, AAAT = 0xFF 
} 

其实我走得更远,并创建一个结构DNAx16或DNAx32在您的机器上有效使用本机字大小。

然后,您可以在数据类型上定义函数,该函数将不得不使用基础位表示,但至少它可以封装它并从这些基元构建更高级别的操作。

相关问题