1

So i have too get two numbers from user input, and find the max of the two numbers without using if statements.

The class is a beginner class, and we have too use what we already know. I kinda worked something out, but it only works if the numbers are inputted with the max number first.

#include <iostream>
using namespace std;


int main()
{
int x = 0, y = 0, max = 0;
int smallest, largest;

cout << "Please enter 2 integer numbers, and i will show you which one is larger:      ";
cin >> x >> y;

smallest = (x < y == 1) + (x - 1);
smallest = (y < x == 1) + (y - 1);

largest = (x < y == 1) + (y - 1);
largest = (y > x == 1) + (x + 1 - 1);

cout << "Smallest: " << smallest << endl;
cout << "Largest: " << largest << endl;



return 0;
}

Thats what i have so far, but after putting different test data in, i found out it only works for numbers such as 4,5 or 6,7. But numbers with more then 2 spaces between eachother they dont such as, 4,8 or 5, 7. Any help would be appreciated.

Tushar
  • 8,019
  • 31
  • 38
KingKong
  • 37
  • 1
  • 9

4 Answers4

2

I saw this question in Cracking the Coding interview book.

Let’s try to solve this by “re-wording” the problem We will re-word the problem until we get something that has removed all if statements

Rewording 1: If a > b, return a; else, return b
Rewording 2: If (a - b) is negative, return b; else, return a
Rewording 3: If (a - b) is negative, let k = 1; else, let k = 0 Return a - k * (a - b)
Rewording 4: Let c = a - b Let k = the most significant bit of c Return a - k * c

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

Source: http://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/098478280X

Edit: This code works even when a-b overflows. Let k equal the sign of a-b such that if a-b >=0, then k is 1, else k=0.Let q be the inverse of k. Above code overflows when a is positive or b is negative, or the other way around. If a and b have different signs, then we want the k to equal sign(a).

/* Flips 1 to 0 and vice-versa */
public static int flip(int bit){
   return 1^bit;
}

/* returns 1 if a is positive, and 0 if a is negative */
public static int sign(int a){
     return flip((a >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1);
}

public static int getMax(int a, int b){
   int c = a - b;
   int sa = sign(a-b);   // if a>=0, then 1 else 0
   int sb = sign(a-b);   // if b>=1, then 1 else 0
   int sc = sign(c);     // depends on whether or not a-b overflows

   /* If a and b have different signs, then k = sign(a) */
   int use_sign_of_a = sa ^ sb;

   /* If a and b have the same sign, then k = sign(a - b) */
   int use_sign_of_c = flip(sa ^ sb);

   int k = use_sign_of_a * sa + use_sign_of_c * sc;
   int q = flip(k);   //opposite of k

   return a * k + b * q;
}
manny
  • 162
  • 1
  • 5
  • Nice for usage with smaller numbers, but this is broken for some edge cases - where `a - b` would be `< std::numeric_limits::min()`. – Tony Delroy Apr 05 '13 at 05:42
  • 1
    You're assuming an integer contains 32 bits. Why not use `(sizeof(int) * CHAR_BIT) - 1`? – David G Apr 05 '13 at 16:23
1

Here is a funny solution:

int max_num = (x>y)*x + (y>=x)*y;
fatihk
  • 7,789
  • 1
  • 26
  • 48
0

You can try this code to find max and min for two input variables.

((a > b) && (max = a)) || (max=b);
((a < b) && (min = a)) ||  (min=b);

For three input variables you can use similar method like this:

int main()
{
    int a = 10, b = 9 , c = 8;
    cin >> a >> b >> c;
    int max  = a, min = a;
    // For Max
    ((a > b) && (a > c) && (max=a)) || 
           ((b > c) && (b > a) && (max=b)) || 
           (max=c) ;

    // For min
    ((a < b) && (a < c) && (min=a)) || 
         ((b < c) && (b < a) && (min=b)) || 
         (min=c) ;

    cout << "max = " << max;
    cout << "and min = " << min;
    return 1;
}

One run is:

:~$ ./a.out 
1
2
3
max = 3 and min = 1

Edit

Thanks to @Tony D: This code will fail for negative numbers.

One may try this for negative numbers for two inputs to find max(not sure for this):

((a > b) && ( a > 0 && (max = a))) ||  ((b > a) && (max = b)) || (max = a);
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • -1 "You can use this code to find max `((a > b) && (max = a)) || (max=b);` - consider `a == 0` and `b = -1`: `a > b` is `true`, so `max = a` is evaluated but yields `false` - the overall expression is then `(false) || (max = b)` so `max = b` runs as well, giving the result `-1`. – Tony Delroy Apr 05 '13 at 05:28
  • @TonyD ok I didn't try for negative number Tony. And Yes you are correct. I would try to update with a correct solution. If you like to improve my answer I will be much happy :) – Grijesh Chauhan Apr 05 '13 at 05:37
  • @TonyD Can you check Edit part Am I correct for max? – Grijesh Chauhan Apr 05 '13 at 05:41
  • Oh yikes... that's so complex it hurts my head to look at it - it's worrying when code isn't self evidently right. To test, I put your code into `char mymax(char a, char b)`, then `for (int ia = -128; ia <= 127; ++ia) for (int ib = -128; ib <= 127; ++ib) if (mymax(ia, ib) != std::max(ia, ib)) std::cout << "broken for " << ia << ' ' << ib << '\n';` - it spews 65022 lines of errors... ;-O Looking at the code, if `a == b` never assigns to max, but many other combinations are broken. – Tony Delroy Apr 05 '13 at 06:02
  • @TonyD :) :) Thanks Tony!!...but I think I should not delete this answer. because it can help upto some extends. Correct na? – Grijesh Chauhan Apr 05 '13 at 06:05
  • 1
    Not my place to say Grijesh, I'm happy for you to do whatever you like. I think there's potential in this kind of approach (your first version worked for many (all?) positive values), and there's potentially value in people seeing the brute-force way I tested your last effort to check every combination of a and b inputs that a signed type allowed (using `char` because 8 bits is manageable time-wise and illustrative of the problems for `int`, with careful conversions between `char` and `int` to make the test work). – Tony Delroy Apr 05 '13 at 06:11
0

Assuming that you have covered bitwise operators already you can do this:

max = a-((a-b)&((a-b)>>(sizeof(int)*8-1)));

This is based off of the solution from Mathematically Find Max Value without Conditional Comparison that @user93353 pointed out in the comments above.

This may be overkill if you really are just trying to avoid if statements, not comparisons in general.

Community
  • 1
  • 1
Robert Harris
  • 482
  • 2
  • 6
  • I think you mean && (logical) not & (bitwise), because in the latter case it will return a-a-b = b if b>a, as the uppermost bit is set. but a-((a-b)&0x00) if a>b, which obivously will lead to 'a' being returned only if b == 0 and maybe in some other cases. – ogni42 Apr 05 '13 at 07:40
  • It definitely is intended to be a bitwise and (&). It worked for several test cases for me. For example: a=5, b=4, max=5; a=1, b=200, max=200; a=0, b=-1, max=0; a=-200, b=-300, max=-200; – Robert Harris Apr 07 '13 at 02:03
  • you are right, I had a twist in my brain. – ogni42 Apr 08 '13 at 10:53