[英]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.