Monday, 27 August 2012

Next highest power of 2

How to calculate the next highest power of 2

I know that I'm hardly the first person to write a blog post on this but I thought I might anyway, so here goes.

How?

The are a few ways to find the highest power of two. I am going to show you 2 ways using code I found on the interwebs (here (Acius' Snippets) and here (Luigi Rizzo's FreeBSD post)).

Via a bad function

This method only works for 8-bit numbers and is a bit crap all up.

UINT16 next_power_of_2(UINT8 x) {
    UINT16 npo2 = x - 1;

    for (UINT8 i = 0; i < 16; i++) {
        npo2 = npo2 | (npo2 >> i);
    }

    return npo2 + 1;
 }

Now let's forget that one.

Via a better function

This method defines a function that finds the next highest power of two. Apparently it is the "Hacker's Delight" algorithm.
Here it is written in C.

unsigned clp2(unsigned x) {
    x = x - 1;
    x = x | (x >> 1);
    x = x | (x >> 2);
    x = x | (x >> 4);
    x = x | (x >> 8);
    x = x | (x >>16);
    return x + 1;
 }

(From here (Acius' Snippets))

Via an inline hash-define

Sometimes in C you need (or would like) to know the next highest power of two without having to call a function (e.g. at compile time). The following set of macros perform the same logic as the function above, but do it in a single, compile-time statement.

#define b2(x)   (   (x) | (   (x) >> 1) )
#define b4(x)   ( b2(x) | ( b2(x) >> 2) )
#define b8(x)   ( b4(x) | ( b4(x) >> 4) )
#define b16(x)  ( b8(x) | ( b8(x) >> 8) )
#define b32(x)  (b16(x) | (b16(x) >>16) )
#define next_power_of_2(x)      (b32(x-1) + 1)

(From here (Luigi Rizzo's FreeBSD post))

How does it work?

It is a little tricky at first glance to figure out what this algorithm is doing. The three main things it does are:
  1. It subtracts 1 from the input to ensure that if the input is a power of 2 (i.e. 4), it doesn't calculate the "next power" to be too large (i.e. in the case of 4, it would return 8 when 4 is actually sufficient). 
  2. It uses a binary divide-and-conquer to cascade the most-significant-bit of the input into all of the bits of lesser significance. 
  3. It adds 1 to get the resulting number to roll-over into the next highest power of 2.
The following is a little pictorial representation of how it works for the number 4098.



Why might it be useful?

Calculating the next highest power of 2 can be extremely handy in programming, especially in C/EmbeddedSystems programming, as powers of 2 are the increments of storage you can allocate in your program.

For example, in a piece of embedded C code I was writing, I created a struct for holding some generic records:

struct my_record
{
    u8_t    flags;
    u8_t    record[MY_RECORD_LENGTH];
    u8_t    padding[PADDING_SIZE];
}__attribute__((__packed__));

I was allowing consumers of this package to define their own "MY_RECORD_LENGTH" but I wanted to determine the PADDING_SIZE to ensure that the length of "struct my_record" was a power of 2 (to remain aligned to power-of-2 byte boundaries). I used the C macro version of the "next power of 2" function along with the known lengths in my_record to create another compile-time value that would be just the right length, as so:

#define PADDING_SIZE (next_power_of_2(1 + MY_RECORD_LENGTH) - (1 + MY_RECORD_LENGTH))

Tuesday, 17 July 2012

Birthday Card

Happy Anniversary the Ningle!

I love you more than anything in the world. I hope this will do as a card! It only works for your name, so you cannot re-gift it (though I don't know why you would want to, maybe because of the really cool hearts).

heart
heart