C 中哪种位操作方法更有效?

发布于 2024-10-10 18:23:01 字数 201 浏览 10 评论 0原文

根据我得到的答案,我认为这个问题有点毫无意义。谢谢大家的热心回复!

我想得到一个二进制数,最右边的j位设置为1,其他设置为0。基本上,有两种方法。我想知道它们哪个更有效,或者有没有比这两个更有效的方法?

1. ~(~0 << j)
2. (1 << j) - 1

Base on the answers i've got, i think this problem is kind of meaningless. Thanks for all your kind replies!

i want to get a binary number with its rightmost j bits set to 1 and others set to be 0. basically, there are two methods. i wanna know which of them is more efficient, or is there a more efficient way than these two?

1. ~(~0 << j)
2. (1 << j) - 1

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

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

发布评论

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

评论(8

琉璃梦幻 2024-10-17 18:23:01

不确定这是否是您正在寻找的答案,但我敢打赌它不会产生超过一纳秒的差异。 :)

或者,换句话说:不要对其进行微优化,除非该单行代码是代码中的瓶颈。

如果您需要其他形式的快速位操作(实际上可能会更慢),请尝试查看编译器内部函数,例如_BitScanForward。如果正确使用的话,这些实际上可能会使您的位操作更快(但在这种情况下不会)。

Not sure if it's the answer you're looking for, but I'll bet it won't make more than a nanosecond of difference. :)

Or, to put it another way: Don't micro-optimize it unless that one-liner is the bottleneck in your code.

If you need other forms of fast bit manipulation that might actually be slower, try looking at the compiler intrinsic functions, like _BitScanForward. Those might actually make your bit operations faster, when used correctly (but not in a situation like this).

尘世孤行 2024-10-17 18:23:01

您正在进行微观优化。您的编译器知道这些操作的最佳翻译。只需写出人眼看起来最干净的一个,然后继续。

You are micro-optimising. Your compiler knows the best translation for those operations. Just write the one that looks the cleanest to the human eye, and move on.

时光与爱终年不遇 2024-10-17 18:23:01

除了已经发布的评论之外:

除了基准测试之外,还检查发出的汇编程序。优化器可能为每个生成相同的代码......

In addition to the comments already posted:

In addition to benchmarking, examine the assembler that's emitted. The optimiser might have produced the same code for each....

白云悠悠 2024-10-17 18:23:01

这是一个懒惰的答案,但是您是否尝试过编写如下所示的简单程序?当然,这是微观优化,但看看是否有任何差异可能会很有趣。

#include <ctime>
main()
{
  int i;
  time_t start = time();
  for (i = 0; i < 1000000; i++)
  {
    // your operation here
  }
  time_t stop = time();
  double elapsed = difftime(stop, start);
}

This is sort of a lazy answer, but have you tried writing a trivial program like the following? Sure it is micro-optimizing, but it might be fun and interesting to see if there is any difference.

#include <ctime>
main()
{
  int i;
  time_t start = time();
  for (i = 0; i < 1000000; i++)
  {
    // your operation here
  }
  time_t stop = time();
  double elapsed = difftime(stop, start);
}
小忆控 2024-10-17 18:23:01

如果您确实想要最快,请使用查找表:

const unsigned numbers[] = {
        0x00000000,
        0x00000001, 0x00000003, 0x00000007, 0x0000000f,
        0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
        0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
        0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
        0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
        0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
        0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
        0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff};

unsigned h(unsigned j) {
        return numbers[j];
}

将其扩展到 64 位作为读者的练习。正如其他人所说,这些都不重要。

If you really want the fastest, use a lookup table:

const unsigned numbers[] = {
        0x00000000,
        0x00000001, 0x00000003, 0x00000007, 0x0000000f,
        0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
        0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
        0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
        0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
        0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
        0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
        0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff};

unsigned h(unsigned j) {
        return numbers[j];
}

Extending this to 64 bits is left as an exercise for the reader. And as others have said, none of this matters.

哆兒滾 2024-10-17 18:23:01

除非将 0 更改为 0U,否则表达式 ~(~0 << j) 具有基于位模式的特定于实现的行为。另一方面,表达式 (1 << j) - 1 是纯算术,其中没有位算术,因此它的值在所有实现中都有明确定义。因此,我总是使用后者。

Unless you change 0 to 0U, the expression ~(~0 << j) has implementation-specific behavior based on bit patterns. On the other hand, the expression (1 << j) - 1 is purely arithmetic and has no bit arithmetic in it, so it's value is well-defined across all implementations. Therefore, I would always use the latter.

心舞飞扬 2024-10-17 18:23:01

真正的答案可能取决于处理器架构。但无论出于何种意图和目的,这几乎肯定是无关紧要的。还要考虑到您的编译器可能会以任何一种方式输出相同的程序集。如果您确实需要知道,请对其进行基准测试,尽管差异几乎肯定太小而无法测量(这是您的答案,但这并不重要)。

The true answer is probably dependent on processor architecture. But for all intents and purposes it's almost certainly irrelevant. Also consider that your complier may output the same assembly either way. If you truly need to know, benchmark it, although the difference will almost certainly be too small to measure (which is your answer, it doesn't matter).

猫七 2024-10-17 18:23:01

无需进行计时实验,只需检查生成的机器代码即可。您会发现 gcc 将它们编译为相同的机器指令。

No timing experiments necessary, just check the generated machine code. You'll find that gcc compiles them both to identical machine instructions.

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