Calcule el mínimo o el máximo de dos números enteros sin bifurcarse

En algunas máquinas raras donde la bifurcación es costosa, el enfoque obvio a continuación para encontrar el mínimo puede ser lento ya que usa la bifurcación.

C++

/* The obvious approach to find minimum (involves branching) */
int min(int x, int y)
{
  return (x < y) ? x : y
}
 
//This code is contributed by Shubham Singh

C

/* The obvious approach to find minimum (involves branching) */
int min(int x, int y)
{
  return (x < y) ? x : y
}

Java

/* The obvious approach to find minimum (involves branching) */
static int min(int x, int y)
{
  return (x < y) ? x : y;
}
 
// This code is contributed by rishavmahato348.

Python3

# The obvious approach to find minimum (involves branching)
def min(x, y):
    return x if x < y else y
 
  # This code is contributed by subham348.

C#

/* The obvious approach to find minimum (involves branching) */
static int min(int x, int y)
{
  return (x < y) ? x : y;
}
 
// This code is contributed by rishavmahato348.

Javascript

<script>
 
/* The obvious approach to find minimum (involves branching) */
function min(x, y)
{
  return (x < y) ? x : y;
}
 
// This code is contributed by subham348.
</script>

A continuación se muestran los métodos para obtener el mínimo (o el máximo) sin usar la ramificación. Sin embargo, por lo general, el enfoque obvio es el mejor.

Método 1 (usar XOR y operador de comparación)
El mínimo de x e y será 

y ^ ((x ^ y) & -(x < y))

Funciona porque si x < y, entonces -(x < y) será -1, que son todos unos (11111….), entonces r = y ^ ((x ^ y) & (111111…)) = y ^ x ^ y = x. 

Y si x>y, entonces-(x<y) será -(0) es decir -(cero) que es cero, entonces r = y^((x^y) & 0) = y^0 = y.

En algunas máquinas, evaluar (x < y) como 0 o 1 requiere una instrucción de bifurcación, por lo que puede no haber ninguna ventaja.
Para encontrar el máximo, utilice 

x ^ ((x ^ y) & -(x < y));

C++

// C++ program to Compute the minimum
// or maximum of two integers without
// branching
#include<iostream>
using namespace std;
 
class gfg
{
     
    /*Function to find minimum of x and y*/
    public:
    int min(int x, int y)
    {
        return y ^ ((x ^ y) & -(x < y));
    }
 
    /*Function to find maximum of x and y*/
    int max(int x, int y)
    {
        return x ^ ((x ^ y) & -(x < y));
    }
    };
     
    /* Driver code */
    int main()
    {
        gfg g;
        int x = 15;
        int y = 6;
        cout << "Minimum of " << x <<
             " and " << y << " is ";
        cout << g. min(x, y);
        cout << "\nMaximum of " << x <<
                " and " << y << " is ";
        cout << g.max(x, y);
        getchar();
    }
 
// This code is contributed by SoM15242

C

// C program to Compute the minimum
// or maximum of two integers without
// branching
#include<stdio.h>
 
/*Function to find minimum of x and y*/
int min(int x, int y)
{
return y ^ ((x ^ y) & -(x < y));
}
 
/*Function to find maximum of x and y*/
int max(int x, int y)
{
return x ^ ((x ^ y) & -(x < y));
}
 
/* Driver program to test above functions */
int main()
{
int x = 15;
int y = 6;
printf("Minimum of %d and %d is ", x, y);
printf("%d", min(x, y));
printf("\nMaximum of %d and %d is ", x, y);
printf("%d", max(x, y));
getchar();
}

Java

// Java program to Compute the minimum
// or maximum of two integers without
// branching
public class AWS {
 
    /*Function to find minimum of x and y*/
    static int min(int x, int y)
    {
    return y ^ ((x ^ y) & -(x << y));
    }
     
    /*Function to find maximum of x and y*/
    static int max(int x, int y)
    {
    return x ^ ((x ^ y) & -(x << y));
    }
     
    /* Driver program to test above functions */
    public static void main(String[] args) {
         
        int x = 15;
        int y = 6;
        System.out.print("Minimum of "+x+" and "+y+" is ");
        System.out.println(min(x, y));
        System.out.print("Maximum of "+x+" and "+y+" is ");
        System.out.println( max(x, y));
    }
 
}

Python3

# Python3 program to Compute the minimum
# or maximum of two integers without
# branching
 
# Function to find minimum of x and y
 
def min(x, y):
 
    return y ^ ((x ^ y) & -(x < y))
 
 
# Function to find maximum of x and y
def max(x, y):
 
    return x ^ ((x ^ y) & -(x < y))
 
 
# Driver program to test above functions
x = 15
y = 6
print("Minimum of", x, "and", y, "is", end=" ")
print(min(x, y))
print("Maximum of", x, "and", y, "is", end=" ")
print(max(x, y))
 
# This code is contributed
# by Smitha Dinesh Semwal

C#

using System;
 
// C# program to Compute the minimum
// or maximum of two integers without 
// branching
public class AWS
{
 
    /*Function to find minimum of x and y*/
    public  static int min(int x, int y)
    {
    return y ^ ((x ^ y) & -(x << y));
    }
 
    /*Function to find maximum of x and y*/
    public  static int max(int x, int y)
    {
    return x ^ ((x ^ y) & -(x << y));
    }
 
    /* Driver program to test above functions */
    public static void Main(string[] args)
    {
 
        int x = 15;
        int y = 6;
        Console.Write("Minimum of " + x + " and " + y + " is ");
        Console.WriteLine(min(x, y));
        Console.Write("Maximum of " + x + " and " + y + " is ");
        Console.WriteLine(max(x, y));
    }
 
}
 
  // This code is contributed by Shrikant13

PHP

<?php
// PHP program to Compute the minimum
// or maximum of two integers without
// branching
 
// Function to find minimum
// of x and y
function m_in($x, $y)
{
    return $y ^ (($x ^ $y) &
            - ($x < $y));
}
 
// Function to find maximum
// of x and y
function m_ax($x, $y)
{
    return $x ^ (($x ^ $y) &
            - ($x < $y));
}
 
// Driver Code
$x = 15;
$y = 6;
echo"Minimum of"," ", $x," ","and",
    " ",$y," "," is "," ";
     
echo m_in($x, $y);
 
echo "\nMaximum of"," ",$x," ",
    "and"," ",$y," ", " is ";
     
echo m_ax($x, $y);
 
// This code is contributed by anuj_67.
?>

Javascript

<script>
// Javascript program to Compute the minimum
// or maximum of two integers without
// branching
 
    /*Function to find minimum of x and y*/
    function min(x,y)
    {
        return y ^ ((x ^ y) & -(x << y));
    }
     
    /*Function to find maximum of x and y*/
    function max(x,y)
    {
        return x ^ ((x ^ y) & -(x << y));
    }
     
    /* Driver program to test above functions */
    let x = 15
    let y = 6
    document.write("Minimum of  "+ x + " and " + y + " is ");
    document.write(min(x, y) + "<br>");
    document.write("Maximum of " + x + " and " + y + " is ");
    document.write(max(x, y) + "\n");
     
    // This code is contributed by avanitrachhadiya2155
</script>

Producción: 

Minimum of 15 and 6 is 6
Maximum of 15 and 6 is 15

Complejidad de tiempo: O(1)

Espacio Auxiliar: O(1)

Método 2 (Usar la resta y el cambio) 
Si sabemos que 

INT_MIN <= (x - y) <= INT_MAX

, entonces podemos usar los siguientes, que son más rápidos porque (x – y) solo necesita evaluarse una vez. 
Mínimo de x e y será 

y + ((x - y) & ((x - y) >>(sizeof(int) * CHAR_BIT - 1)))

Este método cambia la resta de x e y por 31 (si el tamaño del entero es 32). Si (xy) es menor que 0, entonces (x -y)>>31 será 1. Si (xy) es mayor o igual que 0, entonces (x -y)>>31 será 0. 
Entonces, si x >= y, obtenemos mínimo como y + (xy)&0 que es y. 
Si x < y, obtenemos mínimo como y + (xy)&1 que es x.
Del mismo modo, para encontrar el uso máximo 

x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1)))

C++

#include <bits/stdc++.h>
using namespace std;
#define CHARBIT 8
 
/*Function to find minimum of x and y*/
int min(int x, int y)
{
    return y + ((x - y) & ((x - y) >>
            (sizeof(int) * CHARBIT - 1)));
}
 
/*Function to find maximum of x and y*/
int max(int x, int y)
{
    return x - ((x - y) & ((x - y) >>
            (sizeof(int) * CHARBIT - 1)));
}
 
/* Driver code */
int main()
{
    int x = 15;
    int y = 6;
    cout<<"Minimum of "<<x<<" and "<<y<<" is ";
    cout<<min(x, y);
    cout<<"\nMaximum of"<<x<<" and "<<y<<" is ";
    cout<<max(x, y);
}
 
// This code is contributed by rathbhupendra

C

#include<stdio.h>
#define CHAR_BIT 8
 
/*Function to find minimum of x and y*/
int min(int x, int y)
{
  return  y + ((x - y) & ((x - y) >>
            (sizeof(int) * CHAR_BIT - 1)));
}
 
/*Function to find maximum of x and y*/
int max(int x, int y)
{
  return x - ((x - y) & ((x - y) >>
            (sizeof(int) * CHAR_BIT - 1)));
}
 
/* Driver program to test above functions */
int main()
{
  int x = 15;
  int y = 6;
  printf("Minimum of %d and %d is ", x, y);
  printf("%d", min(x, y));
  printf("\nMaximum of %d and %d is ", x, y);
  printf("%d", max(x, y));
  getchar();
}

Java

// JAVA implementation of above approach
class GFG
{
     
static int CHAR_BIT = 4;
static int INT_BIT = 8;
/*Function to find minimum of x and y*/
static int min(int x, int y)
{
    return y + ((x - y) & ((x - y) >>
                (INT_BIT * CHAR_BIT - 1)));
}
 
/*Function to find maximum of x and y*/
static int max(int x, int y)
{
    return x - ((x - y) & ((x - y) >>
            (INT_BIT * CHAR_BIT - 1)));
}
 
/* Driver code */
public static void main(String[] args)
{
    int x = 15;
    int y = 6;
    System.out.println("Minimum of "+x+" and "+y+" is "+min(x, y));
    System.out.println("Maximum of "+x+" and "+y+" is "+max(x, y));
}
}
 
// This code is contributed by 29AjayKumar

Python3

# Python3 implementation of the approach
import sys;
     
CHAR_BIT = 8;
INT_BIT = sys.getsizeof(int());
 
#Function to find minimum of x and y
def Min(x, y):
    return y + ((x - y) & ((x - y) >>
                (INT_BIT * CHAR_BIT - 1)));
 
#Function to find maximum of x and y
def Max(x, y):
    return x - ((x - y) & ((x - y) >>
                (INT_BIT * CHAR_BIT - 1)));
 
# Driver code
x = 15;
y = 6;
print("Minimum of", x, "and",
                    y, "is", Min(x, y));
print("Maximum of", x, "and",
                    y, "is", Max(x, y));
 
# This code is contributed by PrinciRaj1992

C#

// C# implementation of above approach
using System;
 
class GFG
{
     
static int CHAR_BIT = 8;
 
/*Function to find minimum of x and y*/
static int min(int x, int y)
{
    return y + ((x - y) & ((x - y) >>
                (sizeof(int) * CHAR_BIT - 1)));
}
 
/*Function to find maximum of x and y*/
static int max(int x, int y)
{
    return x - ((x - y) & ((x - y) >>
            (sizeof(int) * CHAR_BIT - 1)));
}
 
/* Driver code */
static void Main()
{
    int x = 15;
    int y = 6;
    Console.WriteLine("Minimum of "+x+" and "+y+" is "+min(x, y));
    Console.WriteLine("Maximum of "+x+" and "+y+" is "+max(x, y));
}
}
 
// This code is contributed by mits

Javascript

<script>
// javascript implementation of above approach   
var CHAR_BIT = 4;
    var INT_BIT = 8;
 
    /* Function to find minimum of x and y */
    function min(x , y) {
        return y + ((x - y) & ((x - y) >> (INT_BIT * CHAR_BIT - 1)));
    }
 
    /* Function to find maximum of x and y */
    function max(x , y) {
        return x - ((x - y) & ((x - y) >> (INT_BIT * CHAR_BIT - 1)));
    }
 
    /* Driver code */
        var x = 15;
        var y = 6;
        document.write("Minimum of " + x + " and " + y + " is " + min(x, y)+"<br/>");
        document.write("Maximum of " + x + " and " + y + " is " + max(x, y));
 
// This code is contributed by shikhasingrajput
</script>

Complejidad de tiempo: O(1)

Espacio Auxiliar: O(1)

Tenga en cuenta que la especificación ANSI C de 1989 no especifica el resultado del desplazamiento a la derecha con signo, por lo que el método anterior no es portátil. Si se lanzan excepciones en los desbordamientos, entonces los valores de x e y deben estar sin firmar o convertir a sin firmar para las restas para evitar lanzar una excepción innecesariamente, sin embargo, el desplazamiento a la derecha necesita un operando con signo para producir todos los bits cuando es negativo, así que cast para firmar allí. 

Método 3 (Usar valor absoluto) 

Una fórmula generalizada para encontrar el número máximo/mínimo con valor absoluto es: 

(x + y + ABS(x-y) )/2

Encuentra el número mínimo es: 

(x + y - ABS(x-y) )/2

Entonces, si podemos usar la operación bit a bit para encontrar el valor absoluto, podemos encontrar el número máximo/mínimo sin usar condiciones if. La forma de encontrar la forma absoluta con la operación bit a bit se puede encontrar aquí :

Paso 1) Establezca la máscara como desplazamiento a la derecha de un entero por 31 (suponiendo que los enteros se almacenan como valores de 32 bits en complemento a dos y que el operador de desplazamiento a la derecha sí firma la extensión).

mask = n>>31

Paso 2) XOR la ​​máscara con número

mask ^ n

Paso 3) Reste la máscara del resultado del paso 2 y devuelva el resultado.

(mask^n) - mask 

Por lo tanto, podemos concluir la solución de la siguiente manera:

C++

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
int absbit32(int x, int y)
{
    int sub = x - y;
    int mask = (sub >> 31);
    return (sub ^ mask) - mask;        
 }
 
int max(int x, int y)
{
    int abs = absbit32(x, y);        
    return (x + y + abs) / 2;        
 }
  
int min(int x, int y)
{
    int abs = absbit32(x, y);        
    return (x + y - abs) / 2;
}
  
// Driver Code
int main()
{
    cout << max(2, 3) << endl; //3
    cout <<  max(2, -3) << endl; //2
    cout << max(-2, -3) << endl; //-2
    cout <<  min(2, 3) << endl; //2
    cout << min(2, -3) << endl; //-3
    cout << min(-2, -3) << endl; //-3
 
    return 0;
}
 
// This code is contributed by avijitmondal1998

Java

// Java program for the above approach
 
import java.io.*;
 
class GFG {
     public static void main(String []args){
        System.out.println( max(2,3) ); //3
        System.out.println( max(2,-3) ); //2
        System.out.println( max(-2,-3) ); //-2
        System.out.println( min(2,3) ); //2
        System.out.println( min(2,-3) ); //-3
        System.out.println( min(-2,-3) ); //-3
     }
      
     public static int max(int x, int y){
         int abs = absbit32(x,y);        
         return (x + y + abs)/2;        
     }
      
     public static int min(int x, int y){
         int abs = absbit32(x,y);        
         return (x + y - abs)/2;
     }
      
     public static int absbit32(int x, int y){
         int sub = x - y;
         int mask = (sub >> 31);
         return (sub ^ mask) - mask;        
     }
}

Python3

# Python3 program for the above approach
def max(x, y):
  abs = absbit32(x,y)
  return (x + y + abs)//2     
      
def min(x, y):
  abs = absbit32(x,y)
  return (x + y - abs)//2
      
def absbit32( x, y):
  sub = x - y
  mask = (sub >> 31)
  return (sub ^ mask) - mask      
 
# Driver code
print( max(2,3) ) #3
print( max(2,-3) ) #2
print( max(-2,-3) ) #-2
print( min(2,3) ) #2
print( min(2,-3) ) #-3
print( min(-2,-3) ) #-3
 
# This code is contributed by rohitsingh07052.

C#

// C# program for the above approach
using System;
 
class GFG{
     
public static void Main(String []args)
{
    Console.WriteLine(max(2, 3)); //3
    Console.WriteLine(max(2, -3)); //2
    Console.WriteLine(max(-2, -3)); //-2
    Console.WriteLine(min(2, 3)); //2
    Console.WriteLine(min(2, -3)); //-3
    Console.WriteLine(min(-2, -3)); //-3
}
  
public static int max(int x, int y)
{
    int abs = absbit32(x, y);        
    return (x + y + abs) / 2;        
}
 
public static int min(int x, int y)
{
    int abs = absbit32(x, y);        
    return (x + y - abs) / 2;
}
 
public static int absbit32(int x, int y)
{
    int sub = x - y;
    int mask = (sub >> 31);
    return (sub ^ mask) - mask;        
}
}
 
// This code is contributed by Amit Katiyar

Javascript

<script>
 
// Javascript program for the above approach
 
 function max(x , y){
     var abs = absbit32(x,y);        
     return (x + y + abs)/2;        
 }
  
 function min(x , y){
     var abs = absbit32(x,y);        
     return (x + y - abs)/2;
 }
  
 function absbit32(x , y){
     var sub = x - y;
     var mask = (sub >> 31);
     return (sub ^ mask) - mask;        
 }
 // Drive code
 document.write( max(2,3)+"<br>" ); //3
 document.write( max(2,-3)+"<br>" ); //2
 document.write( max(-2,-3)+"<br>" ); //-2
 document.write( min(2,3)+"<br>" ); //2
 document.write( min(2,-3)+"<br>" ); //-3
 document.write( min(-2,-3) ); //-3
 
// This code is contributed by 29AjayKumar
 
</script>

Complejidad de tiempo: O(1)

Espacio auxiliar: O(1)
Fuente:  
http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *