📌  相关文章
📜  计算不带分支的两个整数的最小值或最大值

📅  最后修改于: 2021-05-06 23:11:13             🧑  作者: Mango

在某些分支机构价格昂贵的稀有机器上,以下明显的最小值查找方法可能会很慢,因为它使用分支机构。

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


C++
// C++ program to Compute the minimum
// or maximum of two integers without
// branching
#include
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
 
/*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


Javascript


C++
#include 
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 "<


C
#include
#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


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;        
     }
}


C#
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


以下是在不使用分支的情况下获得最小值(或最大值)的方法。通常,显而易见的方法是最好的。

方法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
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
 
/*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


Java脚本


输出:

Minimum of 15 and 6 is 6
Maximum 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)。如果(xy)小于0,则(x -y)>> 31将为1。如果(xy)大于或等于0,则(x -y)>> 31将为0。
因此,如果x> = y,我们得到的最小值为y +(xy)&0,即y。
如果x 同样,找到最大的用途

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

C++

#include 
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 "<

C

#include
#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

Java脚本


请注意,1989年的ANSI C规范未指定有符号右移的结果,因此上述方法不可移植。如果在溢出时抛出异常,则x和y的值应为无符号或强制转换为无符号,以免不必要地抛出异常,但是右移需要一个带符号的操作数才能在负数时产生所有一位,因此强制转换在那里签名。

方法3(使用绝对值)

查找具有绝对值的最大/最小值的通用公式是:

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

找到的最小数字是:

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

因此,如果我们可以使用按位运算来找到绝对值,则可以在不使用if条件的情况下找到最大值/最小值。在这里可以找到按位运算的绝对方法:

步骤1)将掩码设置为整数右移31(假设整数存储为2的补码32位值,并且右移运算符符号扩展)。

mask = n>>31

步骤2)将遮罩与数字进行XOR

mask ^ n

步骤3)从步骤2的结果中减去掩码并返回结果。

(mask^n) - mask 

因此,我们可以得出以下结论:

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;        
     }
}

C#

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

Java脚本


来源:
http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax