tags:

views:

212

answers:

3

Hello all :)

I'm looking for a fast way to setup a method of returning a bitmask based on a number. Basically, 4 one bits need to be emitted pre number input. Here's a good idea of what I mean:

foo(1); // returns 0x000F foo(2); // returns 0x00FF foo(3); // returns 0x0FFF foo(4); // returns 0xFFFF

I could just use a big switch statement, but I don't know how wide the input type is in advance. (This is a template function)

Here was the first thing I tried:

template <typename T> T foo(unsigned short length)
{
    T result = 0xF;
    for (unsigned short idx = length; idx > 0; idx--)
    {
        result = (result << 4 | 0xF);
    }
    return result;
}

but it spends a lot of time doing maintenence on the for loop. Any clever ways of doing this I've not thought of?

Billy3

+6  A: 

Just create an array that maps each number to the appropriate bitmask.

e.g. map[1] = 0x00F etc.

This will be the fastest.

Larry Watanabe
Beat me by a second.
GMan
Instead if you use vector won't it be faster as you can use v[1], v[2] etc which will be a constant time operation?
Naveen
Sorry -- I don't know how large the array should be because I don't know the sizeof() the type when the function is called.
Billy ONeal
+8  A: 

How about something like:

template <typename T> T foo(unsigned short length)
{
    return (T(1) << (length * 4)) - 1;
}
Charles Bailey
After spending about 10 minutes figuring out why it works, that kicks A**! Thanks!
Billy ONeal
+2  A: 

If it's just literals, you could even do this at compile-time by using a meta function. Hijacking Charles' idea:

template <typename T, unsigned short L> 
struct Foo {
    enum { result = (T(1) << (L * 4)) - 1 };
};

std::cout << std::setw(4) << std::setfill('0') << std::hex << Foo<int,3>::result;
sbi
Ooohhh! Sweet :) +1. Too bad it's runtime ;)
Billy ONeal