tags:

views:

55

answers:

5

i would like to write a simple line of code, without resorting to if statements, that would evaluate whether a number is within a certain range. i can evaluate from 0 - Max by using the modulus.

30 % 90 = 30  //great

however, if the test number is greater than the maximum, using modulus will simply start it at 0 for the remaining, where as i would like to limit it to the maximum if it's past the maximum

94 % 90 = 4  //i would like answer to be 90

it becomes even more complicated, to me anyway, if i introduce a minimum for the range. for example:

minimum = 10
maximum = 90

therefore, any number i evaluate should be either within range, or the minimum value if it's below range and the maximum value if it's above range

-76 should be 10
2 should be 10
30 should be 30
89 should be 89
98 should be 90
23553 should be 90

is it possible to evaluate this with one line of code without using if statements?

A: 

I don't see how you could...

(X / 10) < 1 ? 10 : (X / 90 > 1 ? 90 : X)

Number divided by 10 is less than 1? set to 10 Else If number divided by 90 is greater than 90, set to 90 Else set to X

Note that it's still hidden ifs. :(

Mike M.
Also note that you should take those parens' placement with a grain of salt! :)
Mike M.
+1  A: 

Using C/C++:

value = min*(number < min) +
        max*(number > max) +
        (number <= max && number >= min)*number%max;

The following is a brief explanation. Note that the code depends on 2 important issues to work correctly. First, in C/C++ a boolean expression can be converted to an integer. Second, the reminder of a negative number is the number it self. So, it is not the mathematical definition of the remainder. I am not sure if this is defined by the C/C++ standards or it is left to the implementation. Basically:

if number < min then:
    value = min*1 +
            max*0 +
            0*number%max;
else if number  > max
    value = min*0 +
            max*1 +
            0*number%max;
else
    value = min*1 +
            max*1 +
            1*number%max;
AraK
+1  A: 

If you are using a language that has a ternary operator (such as C or Java), you could do it like this:

t < lo ? lo : (t > hi ? hi : t)

where t is the test variable, and lo and hi are the limits. That satisfies your constraints, in that it doesn't strictly use if-statements, but the ternary operator is really just syntactic sugar for an if-statement.

Paul A. Hoadley
+2  A: 

simple, but still branches even though if is not used:

r = ( x < minimum ) ? minimum : ( x > maximum ) ? maximum : x;

from bit twiddling hacks, assuming (2<3) == 1:

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

putting it together, assuming min < max:

r = min^(((max^((x^max)&-(max<x)))^min)&-(x<min));

how it works when x<y:

r = y ^ ((x ^ y) & -(x < y));
r = y ^ ((x ^ y) & -(1)); // x<y == 1
r = y ^ ((x ^ y) & ~0); // -1 == ~0
r = y ^  (x ^ y); // (x^y) & ~0 == (x^y)
r = y ^   x ^ y; // y^y == 0
r = x;

otherwise:

r = y ^ ((x ^ y) & -(x < y));
r = y ^ ((x ^ y) & -(0)); // x<y == 0
r = y ^ ((x ^ y) & 0); // -0 == 0
r = y; // (x^y) & 0 == 0
drawnonward
+3  A: 

Probably the simplest way is to use whatever max and min are available in your language like this:

max(10, min(number, 90))

In some languages, e.g. Java, JavaScript, and C# (and probably others) max and min are static methods of the Math class.

I've used a clip function to make it easier (this is in JavaScript):

function clip(min, number, max) {
    return Math.max(min, Math.min(number, max));
}
Matthew Crumley
excellent! this is much easier than trying to use the modulus operator. exactly what i'm looking for. thanks so much.
TheDarkInI1978