首先,这可以是任何语言的通用算法,但我正在学习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);
}
看起来不错......但很难看:) 有没有办法以更优雅的方式实现这一目标? 谢谢!
答案 0 :(得分:2)
假设您要将位字段初始化为零,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中很常见,如果位数不能被{整除,则用于分配一个额外的块{1}}。
你也可以通过
获得所需数量的积分(其中包括Lars在评论中指出的另一个答案)BITS_PER_BLOCK
我发现前一版本更具可读性,但后者也很常见 - 这是使用整数算术的更通用的舍入算法的特例 - C程序员应该对这两种选择都感到满意。
答案 1 :(得分:1)
除非我遗漏了什么,否则我认为它只会是:
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,等等。
答案 2 :(得分:1)
如果你想要n位,那么计算long long
量的正确表达式是:
int bits = n;
int items = (((bits - 1) / CHAR_BIT) / sizeof(long long)) + 1;
答案 3 :(得分:0)
你不应该需要一个循环。如果你进行了bits / sizeof(long long)的除法,你应该得到一个向下舍入的结果。然后,您可以通过执行比特模数%sizeof(long long)检查余数,如果它不为零,则需要在结果中添加一个。
答案 4 :(得分:0)
size_t len_needed(int bits) {
size_t x= bits/(sizeof(long long) * 8);
x = (bits%(sizeof(long long) * 8) ? 1 : 0;
return x;
}
?
:
只是三元运算符,这是执行if / else计算结果值的简短方法。
答案 5 :(得分:0)
这是您的代码,只有一个新值添加到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));
/* ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
}
答案 6 :(得分:0)
#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;
答案 7 :(得分:0)
Number_of_long_longs_for_x= (x + sizeof(long long) - 1)/sizeof(long long)
现在,long long
中的位数为log2(ULLONG_MAX+1)
,而不是sizeof(long long)
。所以你应该重新考虑你的计算。