views:

120

answers:

3

I need to come up with some code that checks if a given integer falls within the bounds of a range. (The range is represented by a pair of integers.)

So, given a range r defined as an std::pair<int, int>, and a test integer n, I want to say:

if (n >= r.first && n <= r.second)

The catch is, I need to use a std::less<int> comparison functor to do this, which means I can only work with the less than operator.

I'm trying to come up with the equivalent expression. I'm pretty sure I have it correct, but I'm not entirely confident.

The expression I came up with is:

( !cmp(n, r.first) && !cmp(r.second, n) )

where cmp is an instance of std::less<int>

Did I do that correctly?

+2  A: 

Yes, not of less-than is equivalent to greater than or equal to, in fact in many older programming languages <= is actually called ngt for not greater than and >= is nlt

tobyodavies
+3  A: 

Polling others is not the best way to verify correctness. :)

Instead, consider your problem. Everything you are dealing with is an int, so all values involved can be represented as an int. No addition or subtraction is involved, so you needn't worry about leaving the representable range. So, we can fall back to standard math using standard integers, and leave the messiness of machine representations behind.

You are given a range closed at both ends [n, m] and a value p to test for membership in that range. You have one operator on integers that you can use, <. All the standard boolean operators are fair game.

Now, you can simply think about sets. You want to reject all p such that p < n or p > m. All other values of p are acceptable. Put another way, p is part of the desired set if

not ((p < n) or (m < p))

Using DeMorgan's laws, this is equivalent to

(not (p < n)) and (not (m < p))

Representing that using the standard C++ operators (rather than the alternative spellings provided by <iso646.h>), we get what you proposed, but using different names:

!<(p, n) && !<(m, p)

Renaming <() to cmp(), n to r.first, m to r.second, and p to n, we get precisely what you proposed:

!cmp(n, r.first) && !cmp(r.second, n)

So, yup, looks correct to me.

Jeremy W. Sherman
A: 

Short answer:

if (num < max && !(num <= min)) { // stuff to do }

This will return true if "num" is between "min" and "max" but is not equal to either of them.

If you need it to include "min" and "max" in the range check, use:

if (num <= max && !(num < min)) { // stuff to do }

This works because...

!(A > B)  == (A <= B)  // If not greater than B, must be less than or equal to B
!(A >= B) == (A < B)   // If not greater or equal to B, must be less than B

!(A < B)  == (A >= B)  // If not less than B, must be greater or equal to B
!(A <= B) == (A > B)   // If not less than or equal to B, must be greater than B
GigaWatt
what if num == max, I'm pretty sure he wants an inclusive range
tobyodavies
Yeah, that's included in it, see the second code snippet.
GigaWatt