从 unsigned int (C++) 读取最左边位的最快方法?

发布于 2024-09-12 07:40:14 字数 41 浏览 2 评论 0原文

从 unsigned int 读取最左边位的最快方法是什么?

What is the fastest way to read the Left-Most bit from unsigned int ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

凯凯我们等你回来 2024-09-19 07:40:14
i >> (sizeof(unsigned int) * CHAR_BIT - 1)

sizeof、乘法和减法将由任何合理的编译器在编译时计算,因此这应该成为单个右移指令,这与您所能获得的速度差不多。

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

The sizeof, multiplication, and subtraction will be computed at compile-time by any reasonable compiler, so this should become a single right-shift instruction, which is about as fast as you will get.

铁轨上的流浪者 2024-09-19 07:40:14

如果 AND 比移位更快,则可能比运行时移位更快:

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

Might be faster than shifting at run-time, if AND is faster than shifting:

i & (1 << (sizeof(unsigned int) * CHAR_BIT - 1))
梦断已成空 2024-09-19 07:40:14

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

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

On a 32-bit system using any compiler that a normal human would use, without odd, esoteric edge cases that C++ geeks can't seem to avoid getting excited about, planet Earth, circa 2010, stars unaligned, a normal day:

if (value & 0x8000000) { ... }
忆离笙 2024-09-19 07:40:14
#define MSB ~(~0U >> 1 )

出于示例目的,假设 8 位 int 将其分解。

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

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

(unsigned int ) a & MSB;
#define MSB ~(~0U >> 1 )

breaking it down assuming 8 bits int for example purposes.

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

then AND this value with what you want to test ( cast as unsigned int )

(unsigned int ) a & MSB;
囍笑 2024-09-19 07:40:14

您当然也可以尝试这个:

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

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

这也应该相当快,因为​​强制转换是编译时的事情,并且实际上并不需要执行 - 它只是告诉编译器使用签名的操作码而不是未签名的操作码。所以我相信需要执行一条指令(CMP?)...

You could of course also try this:

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

And use the fact, that for signed integers, the left most bit is set for negative numbers.

This should also be pretty fast, since the cast is a compile-time thing, and does not really have to be executed - it just tells the compiler to use the signed opcodes as opposed to the unsigned ones. So I believe a single instruction (CMP?) needs to be executed...

策马西风 2024-09-19 07:40:14

这个怎么样?

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

How about this?

i >> numeric_limits<unsigned>::digits - 1;
薔薇婲 2024-09-19 07:40:14

这取决于 int 的大小、字节顺序,以及您是否想要基于内存中方向的最左边位或最高有效位。

猜测您想要最高有效位,在小端、32 位机器(最常见的类型)上,该位将位于内存中 int 位置的第四个字节中。:

i & 0x80000000

现在是寄存器是一个布尔值,表示 MSB 位是否存在。

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

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

Update0

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

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

Well that depends on the size of int, endianness, and whether you want the left most bit based on orientation within memory or the most significant bit.

Guessing that you want the most significant bit, which on a little endian, 32 bit machine (the most common kind), would be in the fourth byte from the ints location in memory.:

i & 0x80000000

Now the register is a boolean for the presence of the MSB bit.

It might be possible to bit shift to the right, this may generate less object code:

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

Update0

Maybe some aren't aware of what I mean above. On the example architecture I gave you could also do this:

((unsigned char *)&i)[3] >> 7
((unsigned char *)&i)[3] & 0x80
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文