2011-11-27 17 views
6

Aquí es la función que se encuentra el mayor de dos números:¿Cómo funciona este código para encontrar el mayor de tres números sin usar ningún operador de comparación?

int larger(int a,int b) 
{ 
    int c=a-b; 
    int k=c>>31&1; 
    int max=a-k*c; 
    return max; 
} 

para encontrar el mayor de tres números, lo llaman como:

larger(a,larger(b,c)); 

¿Cómo funciona esto?

+1

Nota, esto funciona para Java y C#. * Puede * funcionar para C y C++, pero cambiar un número negativo es un comportamiento técnicamente indefinido para esos dos. No culpes a nadie más que a ti mismo si un demonio sale volando de tu nariz. – cHao

+1

El comportamiento está definido por la implementación, no está indefinido. Los demonios nariz no serán observados. –

Respuesta

17
int c=a-b; 

c será negativo si a < b de lo contrario se positivo. Ahora un número negativo tendrá su bit más significativo (MSB) establecido.

int k=c>>31&1; 

Este paso asume que sizeof(int) es 4 bytes y extrae el MSB de c en k. Así k es o bien 0 o 1

int max=a-k*c; 

reemplazando c = a-b en este obtenemos max = a-k*(a-b). Entonces cuando

k = 0, max = a-0*(a-b) 
      = a 

k = 1, max = a-1*(a-b) 
      = b 
+1

'c' será negativo cuando' a

5

Esto solo funciona para enteros de 32 bits, por supuesto.

k=c>>31&1 aísla el bit de signo, que es 0 ó 1.

Si k es 0, entonces a>=b y max = a - 0*(a-b) = a.

Si k es 1, a continuación, a<b y .

Históricamente, la canalización de instrucciones era la razón principal para usar código que evita una prueba if. Si la canalización es profunda y el procesador no utiliza la predicción de bifurcación, una media docena de operaciones enteras puede tomar menos tiempo para hacerlo que el tiempo perdido debido a la recarga de la tubería y el manejo de tiendas especulativas, si las hay. Con la predicción de bifurcación, el código con if (o equivalente) podría ser más rápido. De cualquier manera, el costo de los nanosegundos guardados o perdidos nunca excederá los costos de mantenimiento del programa para ese código.

-3

probar esto .. es muy largo, lo siento: P

while(x && y && z) 
{ 
     x--;y--;z--;c++; 
} 


if(x && y) 
{ 
while(x && y) 
{ 
    x--;y--;c++; 
} 
if(x) c+=x; 
if(y) c+=y; 
} 


if(z && y) 
{ 
while(z && y) 
{ 
    z--;y--;c++; 
} 
if(z) c+=z; 
if(y) c+=y; 
} 

if(x && z) 
{ 
while(x && z) 
{ 
    x--;z--;c++; 
} 
if(x) c+=x; 
if(z) c+=z; 
} 

return c; 
Cuestiones relacionadas