MrD*_*ase 15 c puzzle obfuscation bit-manipulation max
如何以编程方式返回的最大两个整数,而无需使用任何比较运营商和不使用if,else等等?
pli*_*nth 27
max://将MAX(a,b)放入a
a -= b;
a &= (~a) >> 31;
a += b;
Run Code Online (Sandbox Code Playgroud)
和:
int a,b;
min://将MIN(a,b)放入
a -= b;
a &= a >> 31;
a += b;
Run Code Online (Sandbox Code Playgroud)
从这里开始.
http://www.graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
r = x - ((x - y) & -(x < y)); // max(x, y)
Run Code Online (Sandbox Code Playgroud)
你可以通过算术转换(x - y)来使符号位饱和,但这通常就足够了.或者你可以测试高位,总是很有趣.
我想我已经明白了.
int data[2] = {a,b};
int c = a - b;
return data[(int)((c & 0x80000000) >> 31)];
Run Code Online (Sandbox Code Playgroud)
这不行吗?基本上,你取两者的差异,然后根据符号位返回一个或另一个.(这就是处理器无论如何都要大于或小于的程度.)因此,如果符号位为0,则返回a,因为a大于或等于b.如果符号位为1,则返回b,因为从a中减去b导致结果变为负数,表明b大于a.只需确保您的整数是32位签名.
小智 5
在数学世界中:
max(a+b) = ( (a+b) + |(a-b)| ) / 2
min(a-b) = ( (a+b) - |(a-b)| ) / 2
Run Code Online (Sandbox Code Playgroud)
除了在数学上是正确的之外,它没有像移位操作那样对位大小进行假设。
|x| 代表x的绝对值。
没错,绝对值被遗忘了。这对所有a,b的正数或负数均有效