添加和删​​除最后一位

时间:2013-05-23 05:00:38

标签: c++ c bit-manipulation bitwise-operators

我正在尝试使用按位运算来确定下一个和上一个偶数。

例如,对于下一个函数:

x    nextEven(x)
1       2
2       2
3       4
4       4

以及前一个:

x    previousEven(x)
1       0
2       2
3       2
4       4

我有nextEven函数的想法:value = ((value+1)>>1)<<1;

对于previousEven函数,例如:value = ((value)>>1)<<1

有更好的方法吗?没有比较和查看值是偶数还是奇数。

谢谢。

6 个答案:

答案 0 :(得分:4)

执行右移,然后左移以清除LSB效率不高。

我会使用类似的东西:

previous: value &= ~1;
next: value = (value +1) & ~1;

~1可以(通常会)在编译时预先计算,因此previous将在运行时以单个位运算结束。 next可能最终会成为两个操作(增量,and),但仍然应该非常快。

关于你可以从转变中获得的最好的结果是,编译器会认识到你只是清楚地知道LSB,并将其优化为你期望它产生的东西。

答案 1 :(得分:3)

你可以做这样的事情

以前的偶数

unsigned prevev(unsigned x)
{
    return x-(x%2);//bitwise counterpart x-(x&1);
}

接下来的偶数

unsigned nxtev(unsigned x)
{
    return (x%2)+x; //bitwise counterpart x+(x&1);
}

答案 2 :(得分:1)

假设您正在使用unsigned int s,之前的偶数(匹配您的值 - 我们可以争论先前的2甚至2应该是0等)只是x & ~1u。接下来甚至是x + 1的前一个。

答案 3 :(得分:1)

像Duff的设备那样的技巧,或者用XOR交换两个变量,或者使用按位运算来计算下一个和前一个偶数似乎聪明,但它们很少。

作为开发人员,您可以做的最好的事情是首先优化可读性,并且只有在确定导致真正的问题的特定瓶颈后才能解决性能问题。

获取前一个偶数的最佳代码(根据您的定义,前一个偶数2为2)只是写出如下内容:

if ((num % 2) == 1) num--; // num++ for next.

或(略高级):

num -= num % 2;            // += for next.

让疯狂的优化编译器找出最佳的底层代码。

除非您需要每秒数十亿次执行这些操作,否则可读性始终是您最关心的问题。

答案 4 :(得分:1)

以前偶数:
对于之前的偶数,我更喜欢 Jerry Coffin answer

// Get previous even number
unsigned prevEven(unsigned no)
{
    return (no & ~1);
}

下一个偶数:
我尝试只使用按位运算符,但我仍然使用一个一元减( - )运算符来获得下一个数字。

// Get next even number
unsigned nextEven(unsigned no)
{
    return (no & 1) ? (-(~no)) : no ;
}

使用方法nextEven():

  • 如果数字甚至返回相同的数字,
    如果不是偶数,则LSB为0,否则为1 获得数字=>的LSB; number & 1
  • 如果number为odd,则返回数字+ 1,
    将1添加到数字=&gt; -(~number)

答案 5 :(得分:0)

unsigned int previous(unsigned int x)
{
    return x & 0xfffffffe;
}

unsigned int next(unsigned int x)
{
   return previous(x + 2);
}