在一些罕见的机器上,分支是昂贵的,下面显而易见的寻找最小值的方法可能会很慢,因为它使用分支。
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. |
蟒蛇3
# 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> |
下面是在不使用分支的情况下获得最小值(或最大值)的方法。不过,通常来说,显而易见的方法是最好的。
方法1(使用XOR和比较运算符) x和y的最小值为
y ^ ((x ^ y) & -(x < y))
这是因为如果x
如果x>y,那么-(x
在某些机器上,将(x
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 << "Maximum 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 ( "Maximum 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)); } } |
蟒蛇3
# 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 "Maximum 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) + "" ); // This code is contributed by avanitrachhadiya2155 </script> |
输出:
Minimum of 15 and 6 is 6Maximum of 15 and 6 is 15
方法2(使用减法和移位法) 如果我们知道
INT_MIN <= (x - y) <= INT_MAX
,然后我们可以使用下面的公式,因为(x–y)只需要计算一次,所以速度更快。 x和y的最小值为
y + ((x - y) & ((x - y) >>(sizeof(int) * CHAR_BIT - 1)))
此方法将x和y的减法移位31(如果整数的大小为32)。如果(x-y)小于0,那么(x-y)>>31将是1。如果(x-y)大于或等于0,那么(x-y)>>31将为0。 如果x>=y,我们得到的最小值为y+(x-y)&0,也就是y。 如果x
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<< "Maximum 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 ( "Maximum 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 |
蟒蛇3
# 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> |
请注意,1989年的ANSI C规范没有指定有符号右移的结果,因此上述方法不可移植。如果在溢出时引发异常,那么x和y的值应该是无符号的,或者对于减法运算,应该转换为无符号的,以避免不必要地引发异常,但是右移位需要一个有符号的操作数,以便在负时生成所有的一位,因此转换为有符号的。
方法3(使用绝对值)
求具有绝对值的最大/最小数的通用公式为:
(x + y + ABS(x-y) )/2
查找最小值是:
(x + y - ABS(x-y) )/2
因此,如果我们可以使用逐位运算来找到绝对值,我们可以在不使用if条件的情况下找到max/min数。通过按位运算可以找到绝对方式 在这里 :
步骤1)将掩码设置为整数的右移位31(假设整数存储为两个s-补码32位值,且右移位运算符进行符号扩展)。
mask = n>>31
2)用数字对掩模进行异或运算
mask ^ n
步骤3)从步骤2的结果中减去掩码并返回结果。
(mask^n) - mask
因此,我们可以得出如下结论:
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; } } |
蟒蛇3
# 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> |
资料来源: http://graphics.stanford.edu/~seander/bithacks。html#IntegerMinOrMax