从unsigned int读取Left-Most位的最快方法是什么?
答案 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)
也许有些人不知道我的意思。在我给你的示例架构上也可以这样做:
((unsigned char *)&i)[3] >> 7
((unsigned char *)&i)[3] & 0x80