Explain this snippet which finds the maximum of tw

2020-01-24 10:12发布

Find the maximum of two numbers. You should not use if-else or any other comparison operator. I found this question on online bulletin board, so i thought i should ask in StackOverflow

EXAMPLE Input: 5, 10 Output: 10

I found this solution, can someone help me understand these lines of code

int getMax(int a, int b) {  
    int c = a - b;  
    int k = (c >> 31) & 0x1;  
    int max = a - k * c;  
    return max;  
}

19条回答
淡お忘
2楼-- · 2020-01-24 10:35

Use bitwise hacks

r = x ^ ((x ^ y) & -(x < y)); // max(x, y)

If you know that INT_MIN <= x - y <= INT_MAX, then you can use the following, which is faster because (x - y) only needs to be evaluated once.

r = x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // max(x, y)

Source : Bit Twiddling Hacks by Sean Eron Anderson

查看更多
手持菜刀,她持情操
3楼-- · 2020-01-24 10:35

Using the shifting idea to extract the sign as posted by others, here's another way:

max (a, b) = new[] { a, b } [((a - b) >> 31) & 1]

This pushes the two numbers into an array with the maximum number given by the array-element whose index is sign bit of the difference between the two numbers.

Do note that:

  1. The difference (a - b) may overflow.
  2. If the numbers are unsigned and the >> operator refers to a logical right-shift, the & 1 is unnecessary.
查看更多
放荡不羁爱自由
4楼-- · 2020-01-24 10:39
int a=151;
int b=121;
int k=Math.abs(a-b);
int j= a+b;
double k1=(double)(k);
double j1= (double) (j);
double c=Math.ceil(k1/2) + Math.floor(j1/2);
int c1= (int) (c);
System.out.println(" Max value = " + c1);
查看更多
乱世女痞
5楼-- · 2020-01-24 10:41

Here's how I think I'd do the job. It's not as readable as you might like, but when you start with "how do I do X without using the obvious way of doing X, you have to kind of expect that. In theory, this gives up some portability too, but you'd have to find a pretty unusual system to see a problem.

#define BITS (CHAR_BIT * sizeof(int) - 1)

int findmax(int a, int b) { 
    int rets[] = {a, b};
    return rets[unsigned(a-b)>>BITS];
}

This does have some advantages over the one shown in the question. First of all, it calculates the correct size of shift, instead of being hard-coded for 32-bit ints. Second, with most compilers we can expect all the multiplication to happen at compile time, so all that's left at run time is trivial bit manipulation (subtract and shift) followed by a load and return. In short, this is almost certain to be pretty fast, even on the smallest microcontroller, where the original used multiplication that had to happen at run-time, so while it's probably pretty fast on a desktop machine, it'll often be quite a bit slower on a small microcontroller.

查看更多
Emotional °昔
6楼-- · 2020-01-24 10:42

Here are a couple of bit-twiddling methods to get the max of two integral values:

Method 1

int max1(int a, int b) {
  static const size_t SIGN_BIT_SHIFT = sizeof(a) * 8 - 1;
  int mask = (a - b) >> SIGN_BIT_SHIFT;
  return (a & ~mask) | (b & mask);
}

Explanation:

  • (a - b) >> SIGN_BIT_SHIFT - If a > b then a - b is positive, thus the sign bit is 0, and the mask is 0x00.00. Otherwise, a < b so a - b is negative, the sign bit is 1 and after shifting, we get a mask of 0xFF..FF
  • (a & ~mask) - If the mask is 0xFF..FF, then ~mask is 0x00..00 and then this value is 0. Otherwise, ~mask is 0xFF..FF and the value is a
  • (b & mask) - If the mask is 0xFF..FF, then this value is b. Otherwise, mask is 0x00..00 and the value is 0.

Finally:

  • If a >= b then a - b is positive, we get max = a | 0 = a
  • If a < b then a - b is negative, we get max = 0 | b = b

Method 2

int max2(int a, int b) {
  static const size_t SIGN_BIT_SHIFT = sizeof(a) * 8 - 1;
  int mask = (a - b) >> SIGN_BIT_SHIFT;
  return a ^ ((a ^ b) & mask);
}

Explanation:

  • Mask explanation is the same as for Method 1. If a > b the mask is 0x00..00, otherwise the mask is 0xFF..FF
  • If the mask is 0x00..00, then (a ^ b) & mask is 0x00..00
  • If the mask is 0xFF..FF, then (a ^ b) & mask is a ^ b

Finally:

  • If a >= b, we get a ^ 0x00..00 = a
  • If a < b, we get a ^ a ^ b = b
查看更多
仙女界的扛把子
7楼-- · 2020-01-24 10:42

//In C# you can use math library to perform min or max function

using System;

class NumberComparator {

static void Main()
{

    Console.Write(" write the first number to compare: ");
    double first_Number = double.Parse(Console.ReadLine());

    Console.Write(" write the second number to compare: ");
    double second_Number = double.Parse(Console.ReadLine());

    double compare_Numbers = Math.Max(first_Number, second_Number);
    Console.Write("{0} is greater",compare_Numbers);

}

}

查看更多
登录 后发表回答