Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为x位分配n个字节_C_Bit Manipulation - Fatal编程技术网

C 为x位分配n个字节

C 为x位分配n个字节,c,bit-manipulation,C,Bit Manipulation,首先,这可以是任何语言的通用算法,但我正在学习C语言,如果有一些C语言特有的特性,我想知道 我正在编写一个函数,为给定的位数分配足够的内存;转换为long*变量。位数不能为

首先,这可以是任何语言的通用算法,但我正在学习C语言,如果有一些C语言特有的特性,我想知道

我正在编写一个函数,为给定的位数分配足够的内存;转换为
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);
}
int位;//函数参数,检查值是否大于0
大小\u t数据大小;//传递给malloc函数的值

对于(bits=1;bits除非我遗漏了什么,否则我认为它只是:

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,以此类推。

除非我遗漏了什么,否则我认为它只是:

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
大小为8字节,1-64的值将返回8,65-128的值将返回16,等等。

对此不需要循环。如果对位/sizeof(long-long)进行除法,则应得到四舍五入的结果。然后可以通过对位%sizeof(long-long)进行模运算来检查余数,如果不是零,则需要在结果中添加一个。

这不需要循环。如果对位/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;
}
只是三元运算符,这是一种计算为值的if/else的简单方法


只是三元运算符,这是一种执行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));
   /*             ^^^^^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
}
int位;//函数参数,检查值是否大于0
size\u t dataSize;//传递给malloc函数的值

对于(bits=1;bits,这是您的代码,只是在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));
   /*             ^^^^^                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
}
int位;//函数参数,检查值是否大于0
size\u t dataSize;//传递给malloc函数的值
用于(位=1;位
或者如果你知道尺寸的话

nbytes =  (xbits  + 7) / 8;
nllongs = (nbytes + 7) / 8;
或者如果你知道尺寸的话

nbytes =  (xbits  + 7) / 8;
nllongs = (nbytes + 7) / 8;
现在,
long
中的位数是
log2(ULLONG_MAX+1)
,而不是
sizeof(long-long)
。因此您应该重新进行计算


现在,
long
中的位数是
log2(ULLONG_MAX+1)
,而不是
sizeof(long-long)
。因此您应该重新进行计算。

假设您希望将位字段初始化为零,
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);

我发现前一个版本更具可读性,但后一个版本也很常见——这是使用整数算术的更通用的舍入算法的特例——C程序员应该对这两种选择都感到满意。

假设您想将位字段初始化为零,
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);

我发现前一个版本更具可读性,但后一个版本也很常见-这是使用整数算术的更通用的舍入算法的特例-C程序员应该对这两种选择都感到满意。

如果您想要n位,那么计算
long
长度的正确表达式是:

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

如果需要n位,则计算
long
长度的正确表达式为:

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

我不完全理解你的问题。你不能只做dataSize=sizeof(int)吗*bits+padding?padding是指除了对所有答案进行简单的minimumA注释之外,您还想分配额外的字节,真的,但是为什么要假设一个字节中有8位,而有一个非常好的宏字符可以使答案更具可移植性呢?我不完全理解您的问题。您不能只做dataSize=sizeof(int)吗*位+填充?填充是指除了对所有答案的最小注释外,您要分配的额外字节,真的,但为什么要假设一个字节中有8位,而有一个非常好的宏字符可以使答案更便于移植?我最初写的是
long
指针并不重要,但是t最好确保内存的大小可以被
long
的大小整除,因为它在引用它时会尝试获取所有8个字节。我喜欢使用这种方法一步处理“+1”:“数据大小=(位+大小(长)*8-1)/(大小(长)*8)“.@Lars,是的,我喜欢这一行,因为“-1”,加法会导致红利“溢出”到(sizeof(long-long)*8)的下一个倍数,除非位数已经是(sizeof(long-long)*8)的偶数倍。如果你只看一下(bit+7),数学可能更容易理解/8,然后对0到10的位值进行计算(这是我第一次看到这个公式时所遇到的问题)。@Lars我知道-1,我问的是否决票:)我最初写的是
long
指针并不重要,但最好确保内存的大小可以被
long
的大小整除,因为它在引用它时会尝试获取所有8个字节。我喜欢使用这种方法一步处理“+1”:“dataSize=(bits+sizeof(long-long)*8-1)/(sizeof(long-long)*8)@Lars,是的,我喜欢这个一行,因为'-1',加法会导致被除数“溢出”到(sizeof(long-long)*8)的下一个倍数,除非位数是(sizeof(long-long)*8)的偶数倍已经有了。如果你只看(位+7)/8,然后计算出