0

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

3 Answers 3

9

How about something like:

template <typename T> T foo(unsigned short length)
{
    return (T(1) << (length * 4)) - 1;
}
Sign up to request clarification or add additional context in comments.

2 Comments

After spending about 10 minutes figuring out why it works, that kicks A**! Thanks!
@Charles Bailey, well it took me longer than 10 minutes since my template programming is pretty rusty and I have to agree that it is a very nice and elegant solution. The key is to realize that T(1) will be turned into a value of 1 for the type then the one is shifted so that it will be in the next nibble then subtract 1 to get the 0xf. So an example for unsigned short would be 0x0001 then shifted would be 0x0010 then subtract one to get to 0x000f.
6

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

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

This will be the fastest.

2 Comments

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?
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.
2

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;

1 Comment

Ooohhh! Sweet :) +1. Too bad it's runtime ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.