2

I have an size_t variable nOffset that holds a number of which I want to find out how many bytes are actually needed to store it. I guess the position of the MSB could also be used? This is my code so far (sizeof(size_t) is 4):

int nLen = 0;
if (nOffset > 0xFFFFFF)
{
    nLen = 4;
}
else if (nOffset > 0xFFFF)
{
    nLen = 3;
}
else if (nOffset > 0xFF)
{
    nLen = 2;
}
else
{
    nLen = 1;
}
tzippy
  • 6,458
  • 30
  • 82
  • 151
  • An alternative, not necessarily much better, is to use a loop to check whether all except the bottom (least significant) byte has any non-zero bits. – Jonathan Leffler Feb 21 '17 at 07:55
  • 1
    It's better to use formula from information theory, instead of loop: `(size_t)(log(number) / log(2))` – EgorBr Feb 21 '17 at 08:03
  • Actually, the OP's code (which is essentially an unrolled loop) will be faster than a loop, which in turn would be faster than computing logarithms. – Elmar Peise Feb 21 '17 at 08:43
  • 1
    but what are you going to use that information to? if you store variable length data, you also need to store the length – sp2danny Feb 21 '17 at 08:43

4 Answers4

2

You can use following builtin function in GCC

-- Built-in Function: int __builtin_clz (unsigned int x)
Returns the number of leading 0-bits in X, starting at the most significant bit position. If X is 0, the result is undefined.

-- Built-in Function: int __builtin_clzl (unsigned long)
Similar to __builtin_clz, except the argument type is unsigned long.

-- Built-in Function: int __builtin_clzll (unsigned long long)
Similar to __builtin_clz, except the argument type is unsigned long long.

After finding number of leading zeros, it is simple calculations (num_bits = number of bits in int - leading zeros) to find the number of bits required. You can change to number of bytes required with (num_bits + 7) / 8.

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
2

If you are looking for how many bytes are taken by an int variable, you can look into the limits.h library, especially the INT_MIN and INT_MAX constants, then the number of bytes can be calculated.

If you are looking for how many bytes are needed to encode a certain integer, either

  1. Use an algorithm, find the smallest power of 2 pow(2, N) that's equal or larger than the integer, N would be the minimal number of bits. This is straightforward but has a small catch when the integer is negative, see https://softwareengineering.stackexchange.com/questions/239036/how-are-negative-signed-values-stored.

  2. Or try to print out the bits of the number and count them, see C printing bits.

Community
  • 1
  • 1
Neo X
  • 947
  • 7
  • 9
1

It is much easier to use a loop and predefined constants.

Divide the integer by the maximum value of a byte can represent plus one, until you get zero. The iteration count are the bytes.

The following outputs the number of bytes needed to store the precision of the integer:

size_t a = SIZE_MAX;

size_t bytes = 0;
while( a != 0 )
{
    a /= ( 1u << CHAR_BIT );
    bytes++;
}
2501
  • 25,460
  • 4
  • 47
  • 87
0

Simply iterate through the data starting at the MSB, and mask each byte with 0xFF. To know which byte that is the MSB portabily, you have to use bit shifts.

In this snippet, i is the number of bits to shift.

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;
Lundin
  • 195,001
  • 40
  • 254
  • 396