2014-09-18 39 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在您的機器上有效使用本機字大小。

然後,您可以在數據類型上定義函數,該函數將不得不使用基礎位表示,但至少它可以封裝它並從這些基元構建更高級別的操作。

相關問題