Nick
Nick

Reputation: 25799

Datatype size for number of bits

So I have the following function:

static int calcDTSize( int depth )
{
    if ( depth <= 8 )
    {
        return 1;
    }
    if ( depth <= 16 )
    {
        return 2;
    }
    if ( depth <= 32 )
    {
        return 4;
    }
    if ( depth <= 64 )
    {
        return 8;
    }

    throw std::exception( "Invalid bit count" );
}

Which calculates the size of datatype required for the specified number of bits. Originally I just had:

return ( (int) std::ceil( (double) depth / 8.0 ) );

However, on most machines that I know of, there isn't a datatype which is 3 bytes long.

I'm sure there must be a neater way of doing the calculation without the if statements but I can't think how.

Anyone got a better solution?

Upvotes: 1

Views: 261

Answers (4)

aioobe
aioobe

Reputation: 420921

Divide by 8 and round up to closest power of 2.

Considering that the input is limited and the information is completely static, I would however probably put it in a look up array and do

if (depth <= 64)
    return lut[depth];

throw std::exception( "Invalid bit count" );

If you don't want 64 entries in the lut, you could do something like

static int calcDTSize( int depth )
{
  static int lut[] = { 0, 1, 2, 4, 4, 8, 8, 8, 8 };

  if (depth <= 64)
    return lut[(depth - 1 >> 3) + 1];

  throw std::exception();
}

Upvotes: 3

freitass
freitass

Reputation: 6694

This code test for (1) values greater than maximum size, (2) invalid 3 byte data size and (3) values not multiple of 8:

static int calcDTSize( int depth)
{
    if ( (depth <= 64) && (depth != 24) && (depth % 8 == 0) )
        return depth / 8;
    else
        throw std::exception("Invalid bit count");
}

Upvotes: 0

ereOn
ereOn

Reputation: 55726

You may do:

static int calcDTSize( int depth )
{
  const int d = depth / 8;

  if (d < 1) || (d & (d - 1) != 0) || (d > 8)
    throw std::exception("Invalid bit count");

  return d;
}

Where:

const int d = depth / 8;

Simply gives the result of the integer division.

And where:

if (d < 1) || (d & (d - 1) != 0) || (d > 8)

Check if d is between 1 and 8, and is a power of 2.

The trick is that the d & (d - 1) expression returns 0 for all powers of two, and non-zero otherwise.

Upvotes: 0

Jesse Emond
Jesse Emond

Reputation: 7480

return (int) std::pow(2.0, std::ceil((double)depth / 8.0) - 1)

Since they are all powers of 2 you just find the exponent with the division.

Upvotes: 1

Related Questions