How to Find the Larger Number Without Conditional Operators Part 2 (Arithmetic)
Given two (2) signed integer numbers, A and B. Find the larger number between these two (2) variables, using only arithmetic expressions. Provide a solution to the following:
- Assign 0 to X, if A = B, or assign the larger number between A and B
- Assign the larger number between A and B to Y, or assign either A or B, if A = B
Let us start by abstracting the following idea:
- (a) Show A, if A > B
- (b) Show B, if B > A
- (c) Show 0, if A = B
Observe items (a) and (b) and ask, what would it take to know whether A > B or B > A, without using conditional operators? The answer is to get the difference. Let's assign the difference to another variable called C.
- (d) C = B - A
We need to find a solution where we want to show the value of A, if A > B. You can do this by multiplying A with 1 if A > B and zero (0) otherwise.
- (e) (1 or 0) * A
Now, the challenge is to find a similar solution to (e) that will emulate 0 if A < B, and 1 if A > B, using what we know from (d). Let's do some experimentation on expressions, that will give us two (2) distinct values, it does not matter at this moment if it does not result to 1 or 0. How about if we divide C to its absolute value?
- (f)C / |C|
If A > B then C is negative one (-1), else if A < B then C is positive one (+1), else the result of C / |C| is indeterminate (or 0 / 0). We need to find a way mathematically to prevent C from giving indeterminate results while still giving distinction between A > B and A < B.
Let's try some trial and error approach to solve this problem. How about we add + 1 (or K) or Constant to the numerator and denominator?
- (g)(C + 1) / |C + 1|, or (C + K) / |C + K|
The problem with (g) is that, if C = -1, then the result will still be indeterminate. By observation, whatever constant we add to both the numerator and denominator yields indeterminate results if C + K = 0. If this is the case then why not add another variable? And the only variable we have currently is C.
- (h){C + (C + 1)} / |C + C + 1|, or (2C + 1) / |2C + 1|
Item (h) looks promising, but we need 1 and 0 to be multiplied by A. To resolve this, we simply deduct 1 to the result and then we divide by -2.
- (i) [{(2C + 1) / |2C + 1|} - 1] / -2
Let's see the results in a spectrum of values:
Referring back to item (e), we can now multiply item (i) with the variable A, giving us the value of A when A > B, otherwise 0.
- (j) A *[{(2C + 1) / |2C + 1|} - 1] / -2
We can do the same for the variable B. Let's assign D = A - B for simplification purposes.
- (k) B *[{(2D + 1) / |2D + 1|} - 1] / -2
Based on observation, item (j) and item (k) are mutually exclusive and adding these two (2) will yield the greater number. If A = B, then it will result to 0 - This is our solution to the first requirement.
- (l) X = (A *[{(2C + 1) / |2C + 1|} - 1] / -2) +
- (B *[{(2D + 1) / |2D + 1|} - 1] / -2)
We can use the result of item (l) or X, to solve for Y. But first, we need to find a solution wherein we want to multiply either A or B (assuming they are equal) to either 1 (if A = B) or 0 (if A not equal to B).
- (m) (1 or 0) * A
In our table of spectrum of values, we noticed that if A = B, or A < B, the sign of the integer values tends to be the same. We need to make a distinction between A and A < B, furthermore, we need an expression to make the A < B same as A > B, which will satisfy our requirement for item (m).
The solution here is simple, get the absolute value of C and multiply it with -1. Then we follow the steps we did above with some modifications to satisfy item (m), resulting to the following:
The arithmetic expression below replaces item (m):
- (n) E = |C| * -1
- A * [{(2E + 1) / |2E + 1|} + 1] / 2
Item (n) only gives us the value of A, when A = B, but does not give us the value of X or item (l). Since (l) and (n) are mutually exclusive, we can add (l) and (n) resulting to the solution of the second requirement.
- (o) Y = X + A * [{(2E + 1) / |2E + 1|} + 1] / 2
The C++ program below implements the complete solution in finding the larger number between two (2) integer variables using arithmetic expressions.
// Any value here
short A = 10, B = 30;
long C = B - A;
long D = A - B;
// Sets the larger number to X, otherwise set X to 0
long X = (A * (((C + C + 1) / abs(C + C + 1)) - 1) / -2) +
(B * (((D + D + 1) / abs(D + D + 1)) - 1) / -2);
long E = abs(C) * -1;
// Sets the larger number to Y, otherwise set Y to either A or B
long Y = X + A * (((E + E + 1) / abs(E + E + 1)) + 1) / 2;
Since we are using arithmetic expressions to approach this problem, there is a limitation in using variable types. We need to make sure to use variables with enough size to handle the expression based on the limit of the input values.
If you're interested in finding out how to know the larger number between two (2) variables without using conditional and using only bitwise, click here.