12

Is it possible to find the greatest of two integers without any comparison? I found some solutions:

if(!(a/b)) // if a is less than b then division result will be zero.
{
    cout << " b is greater than a";
}
else if (!(a-b)) // we know a is greater than or equal to b now.  check whether they are equal.
{
    cout << "a and b are equal";
}
else
    cout << "a is greater than b";

But if(c) or if(!c) is a comparison to zero. In addition it doesn't work for negative numbers. In fact I need a solution that avoids any if statement. Instead I should use switch statements and arithmetic operators. ThanX.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Ameer Jewdaki
  • 1,758
  • 4
  • 21
  • 36
  • 11
    ... and this is why most of the things you learn about programming in schools today is useless. – Lasse V. Karlsen Jan 24 '09 at 22:55
  • 2
    @LasseV.Karlsen actually this was a useful speedup hack back when there was no hw conditional move. And I don't remember if GPUs now support'em, so there it might still be necessary. Be careful in valuing ignorance :) – Quartz Sep 10 '13 at 10:38
  • And besides being "school" programming problem, this is very common question in programming interviews - when they want to see how you think. – azec-pdx Feb 16 '14 at 14:48
  • 2
    @LasseV.Karlsen: It's not about learning how to compare two integers without any comparison. It's about learning how to think through a problem. Extremely useful. – Lightness Races in Orbit Apr 22 '17 at 22:05

15 Answers15

43

Subtract them and check the sign using nasty bit twiddling hacks
http://graphics.stanford.edu/~seander/bithacks.html

Don't do this in production code if the other programmers know where you live.

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • 2
    Agree with the final last sentence. If this is a good idea for your platform, the compiler should do this optimization for you :) – Laserallan Jan 24 '09 at 23:04
  • b ^ ( (((a-b)>>(sizeof(a)*8-1) & 1) - 1) & (a^b)) I was going to say that a CS course should look below the compiler, but many CPU architectures have MAX and MIN instructions anyway. – Pete Kirkham Jan 24 '09 at 23:30
  • Compare this SO question: http://stackoverflow.com/questions/227383/how-do-i-programmatically-return-the-max-of-two-integers-without#227418 – plinth Jan 25 '09 at 01:07
  • @Laserallan Maybe these students will eventually be writing optimized compilers? –  Mar 03 '15 at 17:00
  • Then they certainly need to know it. I don't like it in production code since the optimization is likely to be architecture dependent and the readability is worse in my opinion. – Laserallan Mar 08 '15 at 21:10
4

Here's a fun bit-twiddling version that doesn't have any conditional branches.

int g = (int)"greater";
int l = (int)"less";
int e = (int)"equal";

int a = 7;
int b = 10;

char *result = (char*)((((a - b) >> 31) & l) | (((b - a) >> 31) & g) | ((~((a - b) | (b - a))) >> 31) & e);
cout << result;
Eclipse
  • 44,851
  • 20
  • 112
  • 171
2

You might exploit the fact that the sign of the calculation a - b depends on which number is greater. This is used in many implementations of comparison. But I believe you'll never be able to completely avoid comparison. In this case, you still at least need to evaluate the contents of the sign flag on the processor.

If you just need to display the lower number you can also use arithmetic tricks:

result = ((a + b) - sqrt((a - b) * (a - b))) / 2

EDIT erm … you're allowed to use switch?

I should use switch statements and arithmetic operators.

switch is basically the same as chained if and as such it also uses comparison. This sounds as if you should indeed just compare to zero to see what sign a - b has.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
1

Not one of the samples presented in the question or any of the answers thus far protects from division by zero. Why on earth are you trying to avoid an 'if' statement? I suspect homework question about ?: operators.

cout << "Maximum is: " << ((a>b)?a:b)

There we go.

It's not possible to compare two numbers without a comparison. You can fudge it and do an indirect operation, but at the end of the day you're comparing something. Trust the compiler to optimize the code and select the best operations.

Adam Hawes
  • 5,439
  • 1
  • 23
  • 30
1
char c;
c=0x3D + (!(b/a) && (a-b)) - (!(a/b) && (a-b));
printf("a %c b",c);
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
1

As a pointless exercise, here's a way of implementing a cond function - to serve the purpose of if, supposing it (and switch, and ?:) had somehow disappeared from the language, and you're using C++0x.

void cond(bool expr, std::function<void ()> ifTrue, std::function<void ()> ifFalse)
{
    std::function<void ()> choices[2] = { ifTrue, ifFalse };
    choices[expr == false]();
}

e.g.

cond(x > y,
    /*then*/ [] { std::cout << "x is greater than y"; },
    /*else*/ [] { std::cout << "x is not greater than y"; });

Like I say, pointless.

Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
0

Try this, tested it, works well.

public static int compare(int a, int b)
{
    int c = a - b;
    return (c >> 31) & 1 ^ 1;
}
Michael0x2a
  • 58,192
  • 30
  • 175
  • 224
0

I think this method is better than others, you can use this logic c and java both programming languages but int should be of 4 byte if int is of 2 byte then make 15 byte right shift instead of 31 byte.

enter code here

#include<stdio.h>

main()
{
   int a, b;
   printf("Enter three numbers\n");
   scanf("%d %d", &a, &b);
   printf("Largest number is %d \n",findMax( a,b ));
}
int findMax( int x, int y)
{
  int z = x - y;
  int i  = (z  >>  31)  &  0x1;
  printf("i = %d shift = %d \n", i, (z>>31));
  int  max  =  x - i  *  z;
  return max;
}
0
(!(a/b) ?  cout << " b is greater than a" : (!(b-a) ? cout << "a and b are equal" :  cout << "a is greater than b") :  cout << "a is greater than b");

That gets a bit messy though

Edit: Is this homework?

fmsf
  • 36,317
  • 49
  • 147
  • 195
0

I just cant see any good reason to do that : who would want to program without "if" ?

a possible answer is :

( ( a + b ) + abs ( a -b ) ) / 2

I guess "abs" just hides a "if" somewhere, just as the ternary operator that is just another name for "if" ...

siukurnin
  • 2,862
  • 17
  • 20
0

The Perverse Idea: use an array of function pointers. Then with some arithmetic and bitwise operations get an index into that array.

Vilx-
  • 104,512
  • 87
  • 279
  • 422
0

To get the greatest number without using comparison/relational operator

void PrintGreatestNumber(int a, int b)
{
   int [] x = new int[] { -1, 0, 1 };
   int greatestNumber =  ((a+b)+ x[ 1 + ((a-b) >> 31) - (-(a-b) >> 31)] * (a-b)) /2;  
   Console.WriteLine(greatestNumber);
}
sudil ravindran pk
  • 2,996
  • 3
  • 24
  • 29
0

You can use a function to check equal or not using xor bitwise operator. here, you can write this function as:

int Check(int a, int b){
    return (a^b);
}

This function will return 0, if two integers are same, otherwise not.

Here, included an example to understand this function.

Let take two integers as a = 1, b= 2

the bits of 1 is --> 00000001 and for 2 is --> 00000010

if we apply xor operation here, we'll get the result as 00000000 which is 0 in integer. because the xor operations are:

1 xor 1 = 0
1 xor 0 = 1
0 xor 1 = 1
0 xor 0 = 0

Another way you can do by subtracting the number like

int Check(int a, int b)
{
   return abs(a-b);
}

The logic here will work as same as before. If we get 0 then it should be equal otherwise not!

Saqib
  • 39
  • 1
  • 7
0

Assume X and Y are the two inputs. X>Y will be: ((X+Y)+ abs(X-Y))/2 and X<Y will be: ((X+Y)- abs(X-Y))/2

Now you can get abs() from #include<math.h>, it actually return the absolute value.

Cheers!

-2
void greater(int a, int b) {
    int c = a - b;
    switch(c) {
        case 0:
            cout << "a and b are equal" << endl;
            break;
        default:
            int d = c & (1<<31);
            switch(d) {
                case 0:
                    cout << "a is bigger than b" << endl;
                    break;
                default:
                    cout << "a is less than b" << endl;
            }
    }
}
Termininja
  • 6,620
  • 12
  • 48
  • 49
Ameer Jewdaki
  • 1,758
  • 4
  • 21
  • 36
  • 3
    well, all those subtract methods have one problem at least: consider a big number a and a small (negative) number b. if you do a-b, then you do in effect "a+b" which can overflow int and will thus possibly be negative. your code would incorrectly assume b is bigger than a then. – Johannes Schaub - litb Jan 24 '09 at 23:54