2011-06-14 68 views
3

我有一個char*緩衝區,我想追加各種位大小的整數(在132之間)到。追加1到32位數字到字符緩衝區

因此,我需要一個函數:

void addBits(char *buffer, int bits_appended_so_far, int object, int object_bit_size); 

可以,比方說,13比特的對象移動到緩衝器的第470比特位置。

我當然可以將這些位逐個移動到緩衝區中,但速度是至關重要的,因此似乎應該可以一次移動較大的塊。有沒有一個標準的方法來做到這一點?似乎應該有一個標準的方法,但一些谷歌搜索和SO搜索沒有給我我想要的。

+0

你究竟想達到什麼目的? libgmp允許對任意大小的整數進行直接位操作,這可能是存儲大字符串的好方法,或者您可以考慮使用'std :: vector '... – 2011-06-14 16:17:39

+0

我看不到矢量會對此有何幫助情況。我不需要動態分配或任何東西。只是一個有效的函數,用於在char數組中添加一個X位大小的對象。 X保證適合int。 – Gurgeh 2011-06-14 16:29:51

+0

'std :: vector '很爛。總有這種感覺,它可以像'std :: vector'一樣使用。 – 2011-06-14 16:35:46

回答

2

怎麼是這樣的:

void addBits(char *buffer, int bits_appended_so_far, int object, int object_bit_size) { 
    int* int_buffer = reinterpret_cast<int*>(buffer); 

    const int bits_per_int = 8 * sizeof(int); 

    int current_int = bits_appended_so_far/bits_per_int; 
    int current_offset = bits_appended_so_far % bits_per_int; 

    int_buffer[current_int] |= object << current_offset; 
    if(current_offset) 
     int_buffer[current_int+1] |= object >> (bits_per_int - current_offset); 
} 

這假定object只設置最低顯著object_bit_size位,否則,你需要添加一個步驟砍額外的(不必要的)位關斷。它還假定在開始添加位之前緩衝區已初始化爲零。

+0

這對我來說已經夠好了(+1並且已被接受),儘管一般情況下它不起作用。將一個隨機指針轉換爲int會導致某些體系結構上的總線錯誤(如果它不是DWORD對齊的)。我曾經在SGI上遇到過這個問題。此外,它假定int對象足夠大,可以處理current_offset的左移,但它沒問題,但我會用很長的代碼(代碼在x86_64上運行就足夠了)。 – Gurgeh 2011-06-15 09:27:32

+0

謝謝。我想你可以通過將輸入int對象分解爲char大小的部分,然後分別將每個部分寫入char *緩衝區來避免int *強制轉換。 (2)移位總是小於int中的位數,所以應該是明確的,所以我不理解你的評論的第二部分。無論如何,希望它能奏效或給你一些想法。 – JohnPS 2011-06-15 20:16:28

0

的最簡單的解決方案似乎是使用鹼性memcpy和適當地偏移,如果位置沒有字節對準

+0

這將打破第一個目標字節的位,但如果我分開處理這個特殊情況,也許這是簡單的足夠。 – Gurgeh 2011-06-14 16:32:33

+0

好點!它會摧毀你的數據 - 我想你必須移動數據來添加一個臨時變量,然後(假設數組已初始化爲全0)... 或者將移位的數據轉換爲臨時變量以及每個字節/字的原始數據並覆蓋原始部分 – 2011-06-14 16:54:34

0

標準字大小爲1,2,4,8和16個字節取決於CPU的,所以可以移一次只有8,16,32,64或128位。沒有標準的方法!

如果你不想用內存空間,我的建議是使用最小單位一個字節,而不是一位,以避免位移和加速功能。

編輯: 如果內存是優先級並且位大小在1到32之間,那麼仍然沒有問題,因爲大多數CPU一次支持多於1位的移位。

在x86下,如果您使用的是32位寄存器,則可以一次移動多達32位。

+0

編號內存優先級爲1,速度優先級爲2,額外的位對我的應用程序確實很重要。 – Gurgeh 2011-06-14 16:40:31

1
  • 使用移位在32位整數中正確對齊位。
  • 查找緩衝區中字節的位置。
  • 如果需要保留緩衝區的內容,請創建一個指向相關字節的int指針,然後按位|該位置的32位int。
  • 如果不需要保存內容,只需memcpy(緩衝區位置,32位int);