从unsigned int(C ++)读取Left-Most位的最快方法?

时间:2010-07-27 14:49:01

标签: c++ bit-manipulation

从unsigned int读取Left-Most位的最快方法是什么?

7 个答案:

答案 0 :(得分:18)

i >> (sizeof(unsigned int) * CHAR_BIT - 1)

sizeof,乘法和减法将在编译时由任何合理的编译器计算,因此这应该成为单个右移指令,大约和你得到的一样快。

答案 1 :(得分:8)

如果AND比移动速度快,可能比在运行时移动更快:

i & (1 << (sizeof(unsigned int) * CHAR_BIT - 1))

答案 2 :(得分:5)

在32位系统上使用普通人将使用的任何编译器,没有奇怪的,深奥的边缘情况,C ++极客似乎无法避免兴奋,地球,大约2010年,星星未对齐,正常的一天:

if (value & 0x8000000) { ... }

答案 3 :(得分:3)

#define MSB ~(~0U >> 1 )

将其分解为假设8位int为例。

0U = 00000000b
~0U = 11111111b
~0U >> 1 = 01111111b
~(~0U >> 1) = 10000000b

然后将此值与您要测试的值(转换为unsigned int)

相对应
(unsigned int ) a & MSB;

答案 4 :(得分:2)

你当然也可以试试这个:

((int) myUint) < 0 // true if set, otherwise false

并使用这一事实,对于有符号整数,最左边的位设置为负数。

这也应该非常快,因为强制转换是一个编译时的事情,并不是真的必须执行 - 它只是告诉编译器使用带符号的操作码而不是无符号操作码。所以我认为需要执行一条指令(CMP?)......

答案 5 :(得分:0)

这个怎么样?

i >> numeric_limits<unsigned>::digits - 1;

答案 6 :(得分:-2)

这取决于int的大小,字节顺序,以及你是否希望最左边的位基于内存中的方向或最重要的位。

猜测你想要一个最重要的位,在一个小端,32位机器(最常见的那种),将位于内存中int位置的第四个字节中。:

i & 0x80000000

现在寄存器是MSB位存在的布尔值。

有可能向右移位,这可能会产生更少的目标代码:

i >> (sizeof(i) * CHAR_BIT - 1)

Update0

也许有些人不知道我的意思。在我给你的示例架构上也可以这样做:

((unsigned char *)&i)[3] >> 7
((unsigned char *)&i)[3] & 0x80