Here is a fast solution for C that works in GCC and Clang; ready to be copied and pasted.
#include <limits.h>unsigned int fls(const unsigned int value){ return (unsigned int)1 << ((sizeof(unsigned int) * CHAR_BIT) - __builtin_clz(value) - 1);}unsigned long flsl(const unsigned long value){ return (unsigned long)1 << ((sizeof(unsigned long) * CHAR_BIT) - __builtin_clzl(value) - 1);}unsigned long long flsll(const unsigned long long value){ return (unsigned long long)1 << ((sizeof(unsigned long long) * CHAR_BIT) - __builtin_clzll(value) - 1);}
And a little improved version for C++.
#include <climits>constexpr unsigned int fls(const unsigned int value){ return (unsigned int)1 << ((sizeof(unsigned int) * CHAR_BIT) - __builtin_clz(value) - 1);}constexpr unsigned long fls(const unsigned long value){ return (unsigned long)1 << ((sizeof(unsigned long) * CHAR_BIT) - __builtin_clzl(value) - 1);}constexpr unsigned long long fls(const unsigned long long value){ return (unsigned long long)1 << ((sizeof(unsigned long long) * CHAR_BIT) - __builtin_clzll(value) - 1);}
The code assumes that value
won't be 0
. If you want to allow 0, you need to modify it.