Mathematically Find Max Value without Conditional Comparison

Viewed 27675

----------Updated ------------

codymanix and moonshadow have been a big help thus far. I was able to solve my problem using the equations and instead of using right shift I divided by 29. Because with 32bits signed 2^31 = overflows to 29. Which works!

Prototype in PHP

$r = $x - (($x - $y) & (($x - $y) / (29)));

Actual code for LEADS (you can only do one math function PER LINE!!! AHHHH!!!)

DERIVDE1 = IMAGE1 - IMAGE2;
DERIVED2 = DERIVED1 / 29;
DERIVED3 = DERIVED1 AND DERIVED2;
MAX = IMAGE1 - DERIVED3;

----------Original Question-----------
I don't think this is quite possible with my application's limitations but I figured it's worth a shot to ask.

I'll try to make this simple. I need to find the max values between two numbers without being able to use a IF or any conditional statement.

In order to find the the MAX values I can only perform the following functions

Divide, Multiply, Subtract, Add, NOT, AND ,OR

Let's say I have two numbers

A = 60;
B = 50;

Now if A is always greater than B it would be simple to find the max value

MAX = (A - B) + B;
ex. 
10 = (60 - 50)
10 + 50 = 60 = MAX

Problem is A is not always greater than B. I cannot perform ABS, MAX, MIN or conditional checks with the scripting applicaiton I am using.

Is there any way possible using the limited operation above to find a value VERY close to the max?

18 Answers

I guess this one would be the most simplest if we manage to find difference between two numbers (only the magnitude not sign)

max = ((a+b)+|a-b|)/2;

where |a-b| is a magnitude of difference between a and b.

This is my implementation using only +, -, *, %, / operators

using static System.Console;

int Max(int a, int b) => (a + b + Abs(a - b)) / 2;
int Abs(int x) => x * ((2 * x + 1) % 2);

WriteLine(Max(-100, -2) == -2); // true
WriteLine(Max(2, -100) == 2);   // true

I just came up with an expression: (( (a-b)-|a-b| ) / (2(a-b)) )*b + (( (b-a)-|b-a| )/(2(b-a)) )*a which is equal to a if a>b and is equal to b if b>a

when a>b: a-b>0, a-b = |a-b|, (a-b)-|a-b| = 0 so the coeficcient for b is 0

b-a<0, b-a = -|b-a|, (b-a)-|b-a| = 2(b-a) so the coeficcient for a is 2(b-a)/2(b-a) which is 1 so it would ultimately return 0*b+1*a if a is bigger and vice versa

Find MAX between n & m

MAX = ( (n/2) + (m/2) + ( ((n/2) - (m/2)) * ( (2*((n/2) - (m/2)) + 1) % 2) ) )
Using #define in c:
#define MAX(n, m) ( (n/2) + (m/2) + ( ((n/2) - (m/2)) * ( (2*((n/2) - (m/2)) + 1) % 2) ) )
or
#define ABS(n) ( n * ( (2*n + 1) % 2) )  // Calculates abs value of n
#define MAX(n, m) ( (n/2) + (m/2) + ABS((n/2) - (m/2)) )  // Finds max between n & m
#define MIN(n, m) ( (n/2) + (m/2) - ABS((n/2) - (m/2)) )  // Finds min between n & m
using System;
namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            float a = 101, b = 15;
            float max = (a + b) / 2 + ((a > b) ? a - b : b - a) / 2;            
        }
    }
}
Related