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

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

max://将MAX(a,b)放入a

 a -= b; a &= (~a) >> 31; a += b; 

和:

int a,b;

min://将MIN(a,b)放入

 a -= b; a &= a >> 31; a += b; 

从这里 。

http://www.graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax

 r = x - ((x - y) & -(x < y)); // max(x, y) 

您可以通过算术移位(x - y)来使符号位饱和,但这通常就足够了。 或者你可以测试高位,总是很有趣。

我想我已经明白了。

 int data[2] = {a,b}; int c = a - b; return data[(int)((c & 0x80000000) >> 31)]; 

这不行吗? 基本上,你取两者的差异,然后根据符号位返回一个或另一个。 (这就是处理器无论如何都要大于或小于的程度。)因此,如果符号位为0,则返回a,因为a大于或等于b。 如果符号位为1,则返回b,因为从a中减去b导致结果变为负数,表明b大于a。 只需确保您的整数是32位签名。

在数学世界中:

 max(a+b) = ( (a+b) + |(ab)| ) / 2 min(ab) = ( (a+b) - |(ab)| ) / 2 

除了在数学上正确之外,它不会对变换操作需要做的位大小做出假设。

|x| 代表x的绝对值。

评论:

你是对的,绝对的价值被遗忘了。 这应该适用于所有a,b正面或负面

返回(a> b?a:b);

要么

 int max(int a, int b) { int x = (a - b) >> 31; int y = ~x; return (y & a) | (x & b); } 

不像上面那样时髦……但……

 int getMax(int a, int b) { for(int i=0; (i 

由于这是一个难题,解决方案将有点复杂:

 let greater xy = signum (1+signum (xy)) let max ab = (greater ab)*a + (greater ba)*b 

这是Haskell,但在任何其他语言中都是一样的。 C / C#人应该使用“sgn”(或“sign”?)而不是signum。

请注意,这将适用于任意大小和实数的内联。

来自z0mbie(着名的virii作家)文章“Polymorphic Games”,也许你会发现它很有用:

 #define H0(x) (((signed)(x)) >> (sizeof((signed)(x))*8-1)) #define H1(a,b) H0((a)-(b)) #define MIN1(a,b) ((a)+(H1(b,a) & ((b)-(a)))) #define MIN2(a,b) ((a)-(H1(b,a) & ((a)-(b)))) #define MIN3(a,b) ((b)-(H1(a,b) & ((b)-(a)))) #define MIN4(a,b) ((b)+(H1(a,b) & ((a)-(b)))) //#define MIN5(a,b) ((a)<(b)?(a):(b)) //#define MIN6(a,b) ((a)>(b)?(b):(a)) //#define MIN7(a,b) ((b)>(a)?(a):(b)) //#define MIN8(a,b) ((b)<(a)?(b):(a)) #define MAX1(a,b) ((a)+(H1(a,b) & ((b)-(a)))) #define MAX2(a,b) ((a)-(H1(a,b) & ((a)-(b)))) #define MAX3(a,b) ((b)-(H1(b,a) & ((b)-(a)))) #define MAX4(a,b) ((b)+(H1(b,a) & ((a)-(b)))) //#define MAX5(a,b) ((a)<(b)?(b):(a)) //#define MAX6(a,b) ((a)>(b)?(a):(b)) //#define MAX7(a,b) ((b)>(a)?(b):(a)) //#define MAX8(a,b) ((b)<(a)?(a):(b)) #define ABS1(a) (((a)^H0(a))-H0(a)) //#define ABS2(a) ((a)>0?(a):-(a)) //#define ABS3(a) ((a)>=0?(a):-(a)) //#define ABS4(a) ((a)<0?-(a):(a)) //#define ABS5(a) ((a)<=0?-(a):(a)) 

干杯

这是一种使用汇编语言的作弊行为,但它仍然很有趣:

 // GCC inline assembly int max(int a, int b) { __asm__("movl %0, %%eax\n\t" // %eax = a "cmpl %%eax, %1\n\t" // compare a to b "cmovg %1, %%eax" // %eax = b if b>a :: "r"(a), "r"(b)); } 

如果你想严格遵守规则并说cmpl指令对此是非法的,那么以下(效率较低)序列将起作用:

 int max(int a, int b) { __asm__("movl %0, %%eax\n\t" "subl %1, %%eax\n\t" "cmovge %0, %%eax\n\t" "cmovl %1, %%eax" :: "r"(a), "r"(b) :"%eax"); } 
 int max(int a, int b) { return ((a - b) >> 31) ? b : a; }