We describe
WITHIN without mentioning circular number
spaces (an undefined term) or providing the code. Here is a
number line with the overflow point (
o) at the far right and
the underflow point (
u) at the far left:
u---------------o
There are two cases to consider: either the
n2 | u2... n3 | u3 range straddles the overflow/underflow
points or it does not. Lets examine the non-straddle case
first:
u-----[.....)-----o
The [ denotes
n2 | u2, the ) denotes
n3 | u3,
and the dots and [ are numbers
WITHIN the range.
n3 | u3 is greater than
n2 | u2, so the
following tests will determine if
n1 | u1 is
WITHIN n2 | u2 and
n3 | u3:
n2 | u2 <= n1 | u1 and n1 | u1 < n3 | u3.
In the case where the comparison range straddles the
overflow/underflow points:
u.....)-----[.....o
n3 | u3 is less than
n2 | u2 and the following
tests will determine if
n1 | u1 is
WITHIN
n2 | u2 and
n3 | u3:
n2 | u2 <= n1 | u1 or n1 | u1 < n3 | u3.
WITHIN must work for both signed and unsigned arguments.
One obvious implementation does not work:
Assume two's-complement arithmetic on a 16-bit machine, and
consider the following test:
33000 32000 34000 WITHIN
The above implementation returns
false for that test,
even though the unsigned number 33000 is clearly within the
range {{32000 ... 34000}}.
The problem is that, in the incorrect implementation, the
signed comparison
< gives the wrong answer when 32000
is compared to 33000, because when those numbers are treated
as signed numbers, 33000 is treated as negative 32536, while
32000 remains positive.
Replacing
< with
U< in the above implementation
makes it work with unsigned numbers, but causes problems with
certain signed number ranges; in particular, the test:
would give an incorrect answer.
For two's-complement machines that ignore arithmetic overflow
(most machines), the following implementation works in all
cases: