我有一个数学函数,取决于三个变量{n,a和b},它们分别由

{a = n + 1,b = n}当n为偶数时

{b = n + 1,a = n},当n为奇数时

我的函数被多次调用,并带有各种n。有没有一种有效的方法来实现这一目标?我认为switchif语句从长远来看可能没有那么高效。

编辑:这是一个最小的示例:

void func(int n)
{
    int a, b;
    if(!(n%2))
    {
        a=n+1;
        b=n;
    }
    else
    {
        a=n;
        b=n+1;
    }
    //continue ...
}

最佳答案

只要所使用的数字系统是二进制补码(即-1 ==〜0),就可以使用以下方法:

  int odd = n & 1;
  a = n + !odd;    // Adds one if n is even
  b = n + odd;     // adds one if n is odd.

此解决方案既避免了% 2,又避免了if,即使2甚至比& 1变得更多。它应该比if解决方案快得多,并且可能比% 2好一点。

如果不知道数字系统是补数(并且数字可以是负数),则可以避免以下情况:
 int odd = !!(n % 2);  // using !! to ensure 0 or 1 value.
 a = n + !odd;
 b = n + odd;

这与我的第一个代码的逻辑相同,但避免依赖于二进制补码。尽管我不知道今天有任何通用的处理器不是二进制补码的(或者甚至在过去的20多年里已经投入生产),毫无疑问,有人会告诉我我错了,有些仍在制作受欢迎的模型...)。

与性能一样,请确保您知道什么是瓶颈,并且只有在代码出现在前10名中时才“弄乱”代码,并测量新代码和旧代码,以确保新代码实际上是一种改进。

08-05 17:32
查看更多