簡體   English   中英

為x位分配n個字節

[英]Allocate n bytes for x bits

首先,這可以是任何語言的通用算法,但我正在學習C,如果有一些C特定的功能,我想知道!

我正在編寫一個函數,為給定的位數分配足夠的內存; long long *變量。 位數不能< 1 我測試了算法:

int bits;  // the function argument, checked for value > 0
size_t dataSize;  // the value passed to the malloc function

for (bits = 1; bits<100; bits++) {
   if (bits < sizeof(long long)) {
      dataSize = 1;
   } else {
      dataSize = (bits + (sizeof(long long) - (bits % sizeof(long long)))) / sizeof(long long);
   }

   printf("%d = %d\n", bits, (int) dataSize);
}

它看起來不錯......但是丑陋:)任何方式都有更優雅的方式來實現這一目標? 謝謝!

假設您要將bit-field初始化為零, calloc()可能比malloc()更可取; 您可能也應該使用無符號類型來避免在比特位時進行有符號的移位。

#include <limits.h>

const size_t BITS_PER_BLOCK = sizeof (long long) * CHAR_BIT;
size_t count = bits / BITS_PER_BLOCK + !!(bits % BITS_PER_BLOCK);
unsigned long long *blocks = calloc(count, sizeof *blocks);

!! 將非零值轉換為1是一種有點hackish的方式,這在C中很常見,如果位數不能被BITS_PER_BLOCK整除,則用於分配一個額外的塊。

您還可以獲得所需數量的塊(作為 - 其中 - Lars在評論中指出另一個答案)

size_t count = (bits + BITS_PER_BLOCK - 1) / BITS_PER_BLOCK;

我發現前一版本更具可讀性,但后者也很常見 - 這是使用整數算術的更通用的舍入算法的特例 - C程序員應該對這兩種選擇都很滿意。

除非我遺漏了什么,否則我認為它只會是:

int bits;
size_t dataSize;

dataSize = bits / (sizeof(long long) * 8);
if( bits % (sizeof(long long) * 8) ) { //Don't add 1 if it was evenly divisible
    dataSize++;
}
dataSize *= sizeof(long long)

因此,假設long long的8字節大小,1-64的值將返回8,65-128將返回16,等等。

如果你想要n位,那么計算long long的正確表達式是:

int bits = n;
int items = (((bits - 1) / CHAR_BIT) / sizeof(long long)) + 1;

你不應該需要一個循環。 如果你進行了bits / sizeof(long long)的除法,你應該得到一個向下舍入的結果。 然后,您可以通過執行比特模數%sizeof(long long)來檢查余數,如果它不為零,則需要在結果中添加一個。

size_t len_needed(int bits) {
   size_t x=  bits/(sizeof(long long) * 8);
   x = (bits%(sizeof(long long) * 8) ? 1 : 0;

   return x;
}

? : thing只是三元運算符,這是執行if / else計算值的簡短方法。

這是你的代碼只有一個新的值添加到printf

int bits;  // the function argument, checked for value > 0
size_t dataSize;  // the value passed to the malloc function

for (bits = 1; bits<100; bits++) {
   if (bits < sizeof(long long)) {
      dataSize = 1;
   } else {
      dataSize = (bits + (sizeof(long long) - (bits % sizeof(long long)))) / sizeof(long long);
   }

   printf("%d = %d (%d)\n", bits, (int) dataSize, 1 + bits/sizeof (long long));
   /*             ^^^^^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
}
#define SIZEOF_LL  sizeof(long long)
nbytes  =  (xbits  + 8         - 1) / 8;
nllongs =  (nbytes + SIZEOF_LL - 1) / SIZEOF_LL;

或者如果你知道尺寸。

nbytes =  (xbits  + 7) / 8;
nllongs = (nbytes + 7) / 8;
Number_of_long_longs_for_x= (x + sizeof(long long) - 1)/sizeof(long long)

現在, long long的位數是log2(ULLONG_MAX+1) ,而不是sizeof(long long) 所以你應該重溫你的計算。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM