Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C/C++;比特旋转_C++_C_Bit Manipulation - Fatal编程技术网

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<代码> ^ 比 > +/>代码低,所以我建议括号。@李杰-既不是C也不是C++授权2S补码。在某些情况下,出于可移植性的原因,最好使用无符号整数并使用~sgn+1的显式2s补码形式。当然,在这种情况下,您会对所有内容使用unsigned(大整数库就是这样做的)。在这种情况下,为了保证可移植的正确性,我会说“必须使用-sgn”,并尝试阻止一些篡改——当然,如果只是为了好玩/学习也没关系。注意——即使您的平台是2s补码(与大多数(如果不是全部)一样),一些最新的编译器也会利用标准语言中的“未定义”进行优化,生成的代码不会达到预期效果。@steve314:是的,我同意2的补码不是强制要求的。但是,整个表达式(不仅仅是
~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