On some rare machines where branching is expensive, the below obvious approach to find minimum can be slow as it uses branching.
c
/* The obvious approach to find minimum (involves branching) */ int min( int x, int y) { return (x < y) ? x : y } |
Below are the methods to get minimum(or maximum) without using branching. Typically, the obvious approach is best, though.
Method 1(Use XOR and comparison operator)
Minimum of x and y will be
y ^ ((x ^ y) & -(x < y))
It works because if x < y, then -(x < y) will be -1 which is all ones(11111….), so r = y ^ ((x ^ y) & (111111…)) = y ^ x ^ y = x.
And if x>y, then-(x<y) will be -(0) i.e -(zero) which is zero, so r = y^((x^y) & 0) = y^0 = y.
On some machines, evaluating (x < y) as 0 or 1 requires a branch instruction, so there may be no advantage.
To find the maximum, use
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. ?> |
Output:
Minimum of 15 and 6 is 6 Maximum of 15 and 6 is 15
Method 2(Use subtraction and shift)
If we know that
INT_MIN <= (x - y) <= INT_MAX
, then we can use the following, which are faster because (x – y) only needs to be evaluated once.
Minimum of x and y will be
y + ((x - y) & ((x - y) >>(sizeof(int) * CHAR_BIT - 1)))
This method shifts the subtraction of x and y by 31 (if size of integer is 32). If (x-y) is smaller than 0, then (x -y)>>31 will be 1. If (x-y) is greater than or equal to 0, then (x -y)>>31 will be 0.
So if x >= y, we get minimum as y + (x-y)&0 which is y.
If x < y, we get minimum as y + (x-y)&1 which is x.
Similarly, to find the maximum use
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 |
Note that the 1989 ANSI C specification doesn’t specify the result of signed right-shift, so above method is not portable. If exceptions are thrown on overflows, then the values of x and y should be unsigned or cast to unsigned for the subtractions to avoid unnecessarily throwing an exception, however the right-shift needs a signed operand to produce all one bits when negative, so cast to signed there.
Method 3 (Use absolute value)
A generalized formula to find the max/min number with absolute value is :
(x + y + ABS(x-y) )/2
Find the min number is:
(x + y - ABS(x-y) )/2
So, if we can use the bitwise operation to find the absolute value, we can find the max/min number without using if conditions. The way to find the absolute way with bitwise operation can be found here:
Step1) Set the mask as right shift of integer by 31 (assuming integers are stored as two’s-complement 32-bit values and that the right-shift operator does sign extension).
mask = n>>31
Step2) XOR the mask with number
mask ^ n
Step3) Subtract mask from result of step 2 and return the result.
(mask^n) - mask
Therefore, we can conclude the solution as follows:
Java
/*package whatever //do not write package name here */ 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; } } |
Source:
http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.