2017-02-21 30 views
0

我有一个size_t变量nOffset,其中包含我想知道实际需要多少字节来存储它。我想MSB的位置也可以使用?这是到目前为止我的代码(sizeof(size_t) 4):如何找出需要多少字节来存储一个值(int)在C

int nLen = 0; 
if (nOffset > 0xFFFFFF) 
{ 
    nLen = 4; 
} 
else if (nOffset > 0xFFFF) 
{ 
    nLen = 3; 
} 
else if (nOffset > 0xFF) 
{ 
    nLen = 2; 
} 
else 
{ 
    nLen = 1; 
} 
+0

另一种方法,不一定要好得多,就是用循环来检查除底部(最低有效)字节以外的所有字节是否有非零位。 –

+1

最好使用信息论中的公式,而不是循环: '(size_t)(log(number)/ log(2))' – EgorBr

+0

实际上,OP的代码(本质上是一个展开的循环)将比一个循环,这反过来会比计算对数更快。 –

回答

1

这是很容易使用循环和预定义的常量。

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

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

size_t a = SIZE_MAX; 

size_t bytes = 0; 
while(a != 0) 
{ 
    a /= (1u << CHAR_BIT); 
    bytes++; 
} 
+0

由于这些值是无符号值,因此可以在一个循环中用简单的a >> = CHAR_BIT;替换a/=(1u << CHAR_BIT);'。 – user694733

+0

@ user694733最初的代码是处理有符号整数。 – 2501

1

可以在GCC

使用以下内置函数 - 内置功能:int __builtin_clz (unsigned int x)
返回X中前导0位的数量,从最高位位置开始。如果X0,结果是未定义的。

- 内置功能:int __builtin_clzl (unsigned long)
类似__builtin_clz,除了参数类型为unsigned long

- 内置功能:int __builtin_clzll (unsigned long long)
类似__builtin_clz,除了参数类型为unsigned long long

找到的前导零的数目后,它是简单的计算(num_bits =在int比特数 - 前导零)找到所需要的比特的数目。您可以更改为(num_bits + 7)/8所需的字节数。

+1

[示例代码](http://ideone.com/H1f1o7)。你可以添加'if(u == 0)return 1;'如果0输入是可能的。 –

+0

'_BitScanReverse'可以在MSVC上用于类似的目的 – sp2danny

+0

OP没有提到GCC,所以我假设他们想要标准C中的解决方案。 – Lundin

1

如果您正在寻找多少字节采取的int变量,你可以看看到limits.h库,特别是INT_MININT_MAX常量,那么可以计算的字节数。

如果你正在寻找需要多少字节编码一定的整数,在

  1. 使用的算法,找到2 pow(2, N)这等于或大于整数长度最小功率,N是最少的位数。这很简单,但是当整数为负数时有一个小错误,请参阅https://softwareengineering.stackexchange.com/questions/239036/how-are-negative-signed-values-stored

  2. 或尝试打印出数字的位数并对它们进行计数,请参阅C printing bits

0

简单地遍历从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; 
相关问题