어떻게 프로그래밍 방식으로 반환하는 최대 두 개의 정수를 사용하지 않고도 비교 연산자를 사용한 경우와 사용하지 않는 경우,다른 사람,etc.?

StackOverflow https://stackoverflow.com/questions/227383

문제

어떻게 프로그래밍 방식으로 반환하는 최대 두 개의 정수를 사용하지 않고도 비교 연산자를 사용한 경우와 사용하지 않은 if, else, 등?

도움이 되었습니까?

해결책

max : // max (a, b)를

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

그리고:

int a, b;

Min : // min (a, b)을 a에 넣습니다.

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

~에서 여기.

다른 팁

http://www.graphics.stanford.edu/~sander/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를 반환합니다. 부호 비트가 1 인 경우, A에서 B를 빼면 결과가 음수로 변하기 때문에 B를 반환합니다. INT가 32bits에 서명했는지 확인하십시오.

수학 세계에서 :

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

수학적으로 정확한 것 외에도 변화하는 작업이 필요하기 때문에 비트 크기에 대해 가정하지 않습니다.

|x| x의 절대 값을 나타냅니다.

논평:

당신이 옳습니다. 절대 가치는 잊혀졌습니다. 이것은 모든 a, b positive 또는 negative에 유효해야합니다.

반환 (a> b? a : b);

또는

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

위만큼 snazzy는 아니지만 ... ...

int getMax(int a, int b)
{
    for(int i=0; (i<a) || (i<b); i++) { }
    return i;
}

이것은 퍼즐이므로 솔루션은 약간 복잡합니다.

let greater x y = signum (1+signum (x-y))

let max a b = (greater a b)*a + (greater b a)*b

이것은 Haskell이지만 다른 언어에서도 동일합니다. C/C# 사람들은 시그널 대신 "SGN"(또는 "부호"?)을 사용해야합니다.

이것은 임의의 크기의 Int와 Real에서도 작동합니다.

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;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top