variable valores utilizar uso usar una trabajar tercera sentencia que programacion numéricas los intercambie intercambiar else elaborar con como auxiliar algoritmo c bit-manipulation max obfuscation puzzle

valores - ¿Cómo devuelvo programáticamente el máximo de dos enteros sin usar ningún operador de comparación y sin usar if, else, etc.?



uso de if en netbeans (10)

¿Cómo devuelvo programáticamente el máximo de dos enteros sin usar ningún operador de comparación y sin usar if , else , etc.?


Como se trata de un rompecabezas, la solución será un poco intrincada:

let greater x y = signum (1+signum (x-y)) let max a b = (greater a b)*a + (greater b a)*b

Este es Haskell, pero será lo mismo en cualquier otro idioma. C / C # personas deberían usar "sgn" (o "signo"?) En lugar de signum.

Tenga en cuenta que esto funcionará en entradas de tamaño arbitrario y en reales también.


Creo que lo tengo.

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

¿Esto no funcionaría? Básicamente, toma la diferencia de los dos y luego regresa uno u otro en función del bit de signo. (Así es como el procesador hace más o menos que de todos modos.) Entonces, si el bit de signo es 0, devuelve a, ya que a es mayor o igual que b. Si el bit de signo es 1, devuelve b, porque restar b de a causa que el resultado sea negativo, lo que indica que b fue mayor que a. Solo asegúrate de que tus entradas tengan 32bits firmados.


Esto es una especie de trampa, usando lenguaje ensamblador, pero no obstante es interesante:

// 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)); }

Si quieres ser estricto con las reglas y decir que la instrucción cmpl es ilegal para esto, entonces la siguiente secuencia (menos eficiente) funcionará:

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"); }


no tan elegante como el anterior ... pero ...

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


return (a> b? a: b);

o

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


Del artículo de z0mbie (escritor de virii famoso) "Juegos polimórficos", tal vez lo encuentres útil:

#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))

aclamaciones


int max(int a, int b) { return ((a - b) >> 31) ? b : a; }



max: // Pondrá MAX (a, b) en una

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

Y:

int a, b;

min: // Pondrá MIN (a, b) en una

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

de aquí .


En el mundo de las matemáticas:

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

Además de ser matemáticamente correcto, no hace suposiciones sobre el tamaño del bit como deben hacer las operaciones de cambio.

|x| representa el valor absoluto de x.

Comentario:

Tienes razón, el valor absoluto fue olvidado. Esto debería ser válido para todos los a, b positivos o negativos