计算不带分支的两个整数的最小值或最大值

在一些罕见的机器上,分支是昂贵的,下面显而易见的寻找最小值的方法可能会很慢,因为它使用分支。

null

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

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享