我有一个功能可以找到最多三个数字,但它使用24个操作我想将它减少到20个操作。仅使用按位运算。
int maxOfThree(int x, int y, int z) {
int a1 = (x+(~y+1))>>31;
int a2 = (x+(~z+1))>>31;
int a3 = (y+(~z+1))>>31;
return ((~a1&((a2&z)|(~a2&x))) | (a1& ((a3&z)|( ~a3&y)))) ;
}
答案 0 :(得分:2)
假设您编写的代码不使用任何“非法”操作(即您可以使用+1),那么您可以编写
#include <stdio.h>
int main(void) {
int x, y, z;
int mxy, mxyz;
x = 5;
y = 123;
z = 9;
mxy = x - ((x - y) & ((x - y) >> 31)); // max(x, y)
mxyz = mxy - ((mxy - z) & ((mxy - z) >> 31));
printf("max is %d\n", mxyz);
}
只有10个操作。每个-
都可以替换为~
和+1
,再添加6个操作。我将把它作为一种练习。要点是 - 您无需单独评估max(x,y)
和max(y,z)
以及max(x,z)
。 max(x,y,z) = max(max(x,y),z)
......这就是你储蓄的来源。
更新仅使用+1
和按位运算符:
#include <stdio.h>
int main(void) {
unsigned int x, y, z, r;
unsigned int mxy, mxyz;
unsigned int xmy;
unsigned int mxymz;
x = 5;
y = 123;
z = 9;
xmy = x + (~y+1); // x minus y
mxy = x + ~(xmy & (xmy >> 31)) + 1; // max(x, y)
mxymz = mxy + (~z+1); // max(x,y) minus z
mxyz = mxy + (~(mxymz & (mxymz >> 31))+1); // max(x,y,z)
printf("max is %d\n", mxyz);
}
总共16个操作(加上3个变量的中间分配,如果你计算那些)。仅使用+ ~ >>
。我认为这很重要。
有几点:
31
确实应该是sizeof(int) * CHAR_BIT - 1
>>31
操作(请参阅https://www.securecoding.cert.org/confluence/display/seccode/INT13-C.+Use+bitwise+operators+only+on+unsigned+operands)