如何在不使用任何比较运算符且不使用if,else等的情况下以编程方式返回两个整数的最大值?

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)

这里开始.


MSN*_*MSN 8

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)来使符号位饱和,但这通常就足够了.或者你可以测试高位,总是很有趣.

  • 好吧,要完全迂腐,你应该谈论分支,而不是比较运算符,因为分支更有可能导致性能问题.但无论如何,这就是为什么我在下面添加了额外的评论,因为x <y相当于获得x-y的高位. (4认同)
  • 没有比较运营商......? (2认同)

Nic*_*ynt 6

我想我已经明白了.

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的正数或负数均有效

  • 你不是把比较隐藏在这里了吗?由于 `abs(x) := x &gt;= 0 ?x:-x`。所以你同样需要一个分支运算符。当然,您可以通过使用 &amp; 掩码来防止分支,但是您必须对操作数的位数做出假设。 (2认同)