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 ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.