我希望在标准C++中将任何大小的整数的前导零位设置为1。
例如:
0001 0011 0101 1111 -> 1111 0011 0101 1111
我找到的所有算法都需要一个相当昂贵的前导零计数。然而,这很奇怪。有非常快速和简单的方法来执行其他类型的位操作,比如:
int y = -x & x; //Extracts lowest set bit, 1110 0101 -> 0000 0001
int y = (x + 1) & x; //Will clear the trailing ones, 1110 0101 - > 1110 0100
int y = (x - 1) | x; //Will set the trailing zeros, 0110 0100 - > 0110 0111
这让我想到,一定有一种简单的代码行通过基本位运算符来设置整数的前导零。希望你能告诉我这是可行的,因为现在我只能将整数位倒序,然后使用快速设置尾随零的方法,再次将整数反转以将前导零设置为1。虽然比使用前导零计数要快得多,但仍然比上面的其他算法慢得多。
template<typename T>
inline constexpr void reverse(T& x)
{
T rev = 0;
size_t s = sizeof(T) * CHAR_BIT;
while(s > 0)
{
rev = (rev << 1) | (x & 0x01);
x >>= 1;
s -= 1uz;
}//End while
x = rev;
}
template<typename T>
inline constexpr void set_leading_zeros(T& x)
{
reverse(x);
x = (x - 1) | x;//Set trailing 0s to 1s
reverse(x);
}
编辑
因为有人询问:我正在使用在早期X86到486DX范围内安装在较旧的CNC机器上运行的MS-DOS。 真是有趣的时光。 :D
clear_leading_ones(x) = ~set_leading_zeroes(~x)
。 - harold