template <typename T>
T rightmostSetBitRemoved(T n)
{
// static_assert(std::is_integral<T>::value && !std::is_signed<T>::value, "type should be unsigned"); // For c++11 and later
return n & (n - 1);
}
Explanation
n
is zero, we have 0 & 0xFF..FF
which is zeron
can be written 0bxxxxxx10..00
and n - 1
is 0bxxxxxx011..11
, so n & (n - 1)
is 0bxxxxxx000..00
.