raw Math
RAW Math Algebra Intervals and Inequalities

Simplifying and Optimizing Interval Conditions

Robert Eisele

Testing whether a value lies inside an interval usually starts with two comparisons:

\[ x\in[a,b] \quad\Longleftrightarrow\quad a\leq x\leq b. \]

In a programming language without chained comparisons, the same condition becomes:

a <= x && x <= b

That form is clear, general, and usually the right default. Still, interval bounds often share terms, integer ranges sometimes permit one-comparison tests, and aligned binary ranges have useful mask identities. The interesting optimization is therefore not replacing every pair of comparisons blindly. It is recognizing structure in a particular interval and choosing an equivalent representation that exposes it.

Center an Interval Around Zero

Assume first that \(a\leq b\) and define the midpoint \(c\) and radius \(r\) by

\[ c=\frac{a+b}{2}, \qquad r=\frac{b-a}{2}. \]

Subtracting the midpoint from all three parts of \(a\leq x\leq b\) gives a symmetric interval:

\[ \begin{array}{rcl} a\leq x\leq b &\Longleftrightarrow& -\dfrac{b-a}{2}\leq x-\dfrac{a+b}{2}\leq\dfrac{b-a}{2}\\[8pt] &\Longleftrightarrow& \left|x-\dfrac{a+b}{2}\right|\leq\dfrac{b-a}{2}. \end{array} \]

An equivalent form without fractions is

\[ \boxed{\left|2x-(a+b)\right|\leq b-a}. \]

The strict interval \(a<x<b\) uses exactly the same expression with \(<\) instead of \(\leq\). These formulas are useful when the bounds already have the form \(c-r\) and \(c+r\):

\[ c-r\leq x\leq c+r \quad\Longleftrightarrow\quad |x-c|\leq r. \]

This is not automatically faster on a scalar processor. It replaces two comparisons with subtraction, absolute value, and one comparison. Its real advantage is algebraic: common terms disappear, symmetry becomes explicit, and SIMD instruction sets often provide an efficient absolute-value operation.

Cancel Shared Terms Before Counting Operations

Bounds generated from the same expression should be simplified before any low-level trick is considered. For example, suppose a moving window is described by

\[ p(t)-r\leq x+q(t)\leq p(t)+r. \]

Centering the interval produces

\[ |x+q(t)-p(t)|\leq r. \]

If \(p(t)\) and \(q(t)\) contain common terms, ordinary algebra may remove more work than changing the comparison strategy. Compilers eliminate constant expressions and common subexpressions well, but they cannot generally infer application-specific identities hidden inside unrelated function calls.

Open and Half-Open Integer Intervals

Over the real numbers, a half-open interval is asymmetric, so one ordinary absolute-value comparison cannot distinguish its two endpoints. Over the integers, an open endpoint can be shifted by one unit. Provided the additions and subtractions do not overflow,

\[ \begin{array}{rcl} a<x\leq b &\Longleftrightarrow& a+1\leq x\leq b,\\[3pt] a\leq x<b &\Longleftrightarrow& a\leq x\leq b-1,\\[3pt] a<x<b &\Longleftrightarrow& a+1\leq x\leq b-1. \end{array} \]

Applying the centered form to these closed integer intervals gives

\[ \begin{array}{rcll} a<x\leq b &\Longleftrightarrow& |2x-(a+b+1)|\leq b-a-1, &b\geq a+1,\\[3pt] a\leq x<b &\Longleftrightarrow& |2x-(a+b-1)|\leq b-a-1, &b\geq a+1,\\[3pt] a<x<b &\Longleftrightarrow& |2x-(a+b)|\leq b-a-2, &b\geq a+2. \end{array} \]

The side conditions matter. They state when the corresponding integer interval is nonempty. In fixed-width code, perform the endpoint adjustment and the doubled arithmetic in a wider type, or retain the original pair of comparisons.

A Pyramid in One Condition

Consider an eleven-column output with indices \(j=0,\ldots,10\). Row \(i\) should contain characters from \(5-i\) through \(5+i\). The direct range check is

\[ 5-i\leq j\leq5+i. \]

The interval is centered at column \(5\) with radius \(i\), so it contracts immediately to

\[ \boxed{|j-5|\leq i}. \]

for (let i = 0; i < 6; i++) {
  let row = "";
  for (let j = 0; j < 11; j++) {
    row += Math.abs(j - 5) <= i ? "X" : " ";
  }
  console.log(row);
}

Here the absolute-value form is not merely shorter. It expresses the geometry directly: print a character when the horizontal distance from the center does not exceed the current row's radius.

Draw ASCII Conditions

One Comparison with Unsigned Subtraction

A closed interval of fixed-width unsigned integers can be tested with one subtraction and one comparison. Let the arithmetic wrap modulo \(2^w\), and assume \(0\leq a\leq b<2^w\). Then

\[ \boxed{a\leq x\leq b \quad\Longleftrightarrow\quad x-a\leq b-a} \qquad\text{in unsigned }w\text{-bit arithmetic}. \]

If \(x<a\), the subtraction \(x-a\) wraps to a large unsigned value and fails the comparison. If \(x\geq a\), subtracting \(a\) simply translates the interval \([a,b]\) to \([0,b-a]\).

function inUint32Range(x, lower, upper) {
  return ((x - lower) >>> 0) <= ((upper - lower) >>> 0);
}

JavaScript's >>> 0 conversion restricts this version to unsigned 32-bit values. In C and C++, use an explicitly unsigned type and perform the subtraction in that type; casting only after a signed subtraction does not prevent signed-overflow problems.

Power-of-Two Blocks as Bit Masks

Bit masks provide an exact interval test when the interval is one aligned block of \(2^k\) unsigned integers. Set

\[ s=2^k, \qquad m=s-1, \qquad a\mathbin{\&}m=0, \qquad b=a+m. \]

The low \(k\) bits may vary freely while every higher bit must match \(a\). Therefore

\[ \boxed{a\leq x\leq b \quad\Longleftrightarrow\quad (x\mathbin{\&}\mathord{\sim}m)=a} \]

and, equivalently,

\[ \boxed{a\leq x\leq b \quad\Longleftrightarrow\quad (x\mathbin{|}m)=b}. \]

For \([12,15]\), the block size is \(4\), the mask is \(3=0011_2\), and \(12=1100_2\) is aligned to that block:

const inBlock = (x & ~3) === 12;
// Equivalent for this block: (x | 3) === 15

The alignment requirement is essential. The interval width is \(b-a=2^k-1\), not a power of two, and an arbitrary interval containing \(2^k\) values cannot be recognized by a single mask if it crosses a block boundary.

Intervals That Wrap Around

Angles, clock values, sequence numbers, and ring-buffer indices live on a cycle rather than a line. For values normalized to \([0,m)\), the forward interval from \(a\) to \(b\) may cross zero. Translating both the test value and the endpoint by \(-a\) gives one uniform condition:

\[ x\in[a,b]_{\mathrm{cyclic}} \quad\Longleftrightarrow\quad (x-a)\bmod m\leq(b-a)\bmod m. \]

function positiveModulo(value, modulus) {
  return ((value % modulus) + modulus) % modulus;
}

function inCyclicInterval(x, lower, upper, modulus) {
  return positiveModulo(x - lower, modulus) <=
    positiveModulo(upper - lower, modulus);
}

This formulation is often clearer than branching between a normal interval and a wrapped one. It is not necessarily cheaper: integer remainder can be expensive unless the modulus is a power of two or the compiler can simplify it.

Know What the Machine May Change

Source-level operation counts are not instruction counts. Optimizing compilers can combine comparisons, generate conditional moves, vectorize absolute-value checks, or preserve a branch when branch prediction is likely to win. Replacing logical AND with bitwise AND merely to force both comparisons to run is therefore not a portable optimization.

Several numerical edge cases also affect which identity is safe:

The best interval condition is usually the one that states the domain model most directly. Use the ordinary two comparisons for arbitrary bounds, the centered form for symmetric geometry, unsigned subtraction for a proven fixed-width integer domain, and masks only for aligned power-of-two blocks. Then benchmark the generated code in its real workload before calling any rewrite faster.