0

根据我得到的答案,我认为这个问题有点毫无意义。感谢您的所有友好回复!

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

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

8 回答 8

3

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

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

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

于 2011-01-07T03:04:57.177 回答
2

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

于 2011-01-07T03:05:39.633 回答
1

除了已经发布的评论:

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

于 2011-01-07T03:07:34.343 回答
1

这是一个懒惰的答案,但是您是否尝试过编写类似以下的简单程序?当然它是微优化,但看看是否有任何区别可能会很有趣。

#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);
}
于 2011-01-07T03:11:58.030 回答
1

如果您真的想要最快的,请使用查找表:

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 位留作读者练习。正如其他人所说,这些都不重要。

于 2011-01-07T03:16:37.560 回答
1

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

于 2011-01-07T04:31:06.227 回答
0

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

于 2011-01-07T03:07:13.727 回答
0

无需时序实验,只需检查生成的机器码即可。你会发现 gcc 将它们编译成相同的机器指令。

于 2011-01-07T04:16:13.490 回答