C++ C/C++;比特旋转
本着这样的精神,我需要解决以下问题:C++ C/C++;比特旋转,c++,c,bit-manipulation,C++,C,Bit Manipulation,本着这样的精神,我需要解决以下问题: int x; int pow2; // always a positive power of 2 int sgn; // always either 0 or 1 // ... // ... if(sgn == 0) x -= pow2; else x += pow2; 当然我需要避免有条件的。到目前为止,我想出的最好的办法是 x -= (1|(~sgn+1))*pow2 但这涉及到一个乘法运算,我也希望避免。提前谢谢 编辑:谢谢大家
int x;
int pow2; // always a positive power of 2
int sgn; // always either 0 or 1
// ...
// ...
if(sgn == 0)
x -= pow2;
else
x += pow2;
当然我需要避免有条件的。到目前为止,我想出的最好的办法是
x -= (1|(~sgn+1))*pow2
但这涉及到一个乘法运算,我也希望避免。提前谢谢
编辑:谢谢大家
x -= (pow2^-sgn) + sgn
似乎是在耍花招 在我的头顶上:
int subMask = sgn - 1;
x -= pow2 & subMask;
int addMask = -sgn;
x += pow2 & addMask;
无法保证它是否有效或者这是否明智,这只是一个突然出现在我脑海中的随机想法
编辑:让我们使其可读性降低一点(即更紧凑):
我会试试看
x -= (pow2 ^ (~sgn+1)) + sgn
或者,正如李杰在评论中所建议的那样
x -= (pow2 ^ -sgn) + sgn
如果
sgn
是0
,~sgn+1
也是0
,那么pow2^(~sgn+1)==pow2
。如果sgn
是1
,(~sgn+1)
是0xffffff
,并且(pow2^(~sgn+1))+sgn==-pow2
,我将更改接口并用左移位替换乘法。(使用指数而不是pow2)您可以执行以下操作(从链接)
x+=((pow2^-sgn)+sgn)@Sven:no,
&
是按位的operator@Sven:不-如果你不相信我,请查看编辑历史记录-有一个|
,我用+
替换了它,但没有条件。@Sven:首先(sgn==0)
不是条件测试,它是(无分支)测试。第二,当我重新阅读问题时,我把它去掉了,发现sgn只能取0和1的值,这使得测试操作变得不必要。正如我所说,从来没有任何条件,也没有人玩任何游戏-你只是犯了一个简单的错误。我称之为暧昧-==通常被称为条件运算符,但显然不是(编辑:本身)选择性执行意义上的条件。@Steve314:任何调用条件运算符的人都是被误导的-其正确名称是相等运算符或等于运算符。这当然不意味着分支,这是本文中性能的主要问题。您可以将~sgn+1
更改为-sgn
。哦,是的。UH<代码> ^ 比~sgn+1
部分)是以2的补码为前提的(否则,条件不能替换)。替换的建议是基于“1种操作优于2种推理”;求反可能和加法一样快,所以求反是浪费时间。那么,你应该接受答案。当乘法不是问题时,我们还有:x-=(1-2*sgn)*pow
,使用映射0->1
和1->-1
,这等于x->(1-2x)
。再次,括号!^
的优先级低于+
,因此'x-=pow2^-sgn+sgn'是x-=pow2^(-sgn+sgn)
是x-=pow2
。
x -= (pow2 ^ (~sgn+1)) + sgn
x -= (pow2 ^ -sgn) + sgn