如何找出在C中存储一个值(int)需要多少字节

如何找出在C中存储一个值(int)需要多少字节,c,bit-shift,bitmask,C,Bit Shift,Bitmask,我有一个size\u t变量nOffset,它包含一个数字,我想知道实际需要多少字节来存储它。我猜MSB的位置也可以使用?这是我到目前为止的代码(sizeof(size\u t)is 4): 使用循环和预定义的常量要容易得多 将整数除以一个字节的最大值可以表示加1,直到得到零。迭代计数是字节数 以下输出存储整数精度所需的字节数: size_t a = SIZE_MAX; size_t bytes = 0; while( a != 0 ) { a /= ( 1u << CHA

我有一个
size\u t
变量
nOffset
,它包含一个数字,我想知道实际需要多少字节来存储它。我猜MSB的位置也可以使用?这是我到目前为止的代码(
sizeof(size\u t)
is 4):


使用循环和预定义的常量要容易得多

将整数除以一个字节的最大值可以表示加1,直到得到零。迭代计数是字节数

以下输出存储整数精度所需的字节数:

size_t a = SIZE_MAX;

size_t bytes = 0;
while( a != 0 )
{
    a /= ( 1u << CHAR_BIT );
    bytes++;
}
size\u t a=size\u MAX;
大小\u t字节=0;
while(a!=0)
{

a/=(1u您可以在中使用以下内置函数

--内置函数:
int\uu内置函数(未签名的int x)

返回X中从最高有效位位置开始的前导0位数。如果
X
0
,则结果未定义

--内置函数:
int\uuuu内置clzl(无符号长)

类似于
\uuuu builtin\u clz
,只是参数类型是
无符号长型

--内置函数:
int\uuuu内置clzll(无符号长字符)

类似于
\uuuu builtin\u clz
,不同的是参数类型是
无符号long


找到前导零的数量后,只需进行简单的计算(num_bits=
int
-前导零中的位数)即可找到所需的位数。您可以使用
(num_bits+7)更改为所需的字节数/8

如果要查找
int
变量占用的字节数,可以查看
limits.h
库,尤其是
int\u MIN
int\u MAX
常量,然后可以计算字节数


如果您正在查找编码某个整数需要多少字节,则

  • 使用一种算法,找到2
    pow(2,N)
    的最小幂,该幂等于或大于整数,N将是最小位数。这很简单,但当整数为负时有一个小陷阱,请参阅

  • 或者试着打印出数字的位数并进行计数,请参见


  • 只需迭代从MSB开始的数据,并用0xFF屏蔽每个字节。要知道哪个字节是MSB端口,必须使用位移位

    在这个代码段中,
    i
    是要移位的位数

    size_t i;
    for(i=sizeof(data)*8; i!=0; i-=8)
    {
      if( (data >> (i-8)) & 0xFF)
      {
        break;
      }
    }
    
    size_t bytes_to_copy = i / 8;
    

    另一种不一定更好的方法是使用循环检查除底部(最低有效)字节外的所有字节是否都有非零位。最好使用信息论公式,而不是循环:
    (size\u t)(log(number)/log(2))
    实际上,OP的代码(本质上是一个展开的循环)将比循环快,而循环又比计算对数快。但您将如何使用这些信息?如果存储可变长度的数据,您还需要存储长度。您可以添加
    if(u==0)如果可以输入0,则返回1;
    \u BitScanReverse
    可以在MSVCOP上用于类似的目的。OP没有提到GCC,所以我假设他们需要标准C的解决方案。由于这些是无符号值,您可以在循环中替换
    a/=(1u>=CHAR\u BIT;
    。@user694733最初代码是处理有符号整数的。
    size_t i;
    for(i=sizeof(data)*8; i!=0; i-=8)
    {
      if( (data >> (i-8)) & 0xFF)
      {
        break;
      }
    }
    
    size_t bytes_to_copy = i / 8;