Scientific Computing · Floating Point
Round-to-Nearest-Even and the Mechanics of Correct Rounding
How an adder decides where to cut a result, what guard, round, and sticky bits encode, and why the tie case resolves toward an even last bit.
An arithmetic operation on two p-bit significands almost never produces a p-bit result. The exact sum of two binary32 numbers can require hundreds of bits before the leading one; the exact product of two 24-bit significands needs 48. The format has 24. Something must be discarded, and the rule for discarding it is not a detail. It determines the error of every subsequent operation, and it is the one part of floating-point arithmetic the standard specifies to the last bit.
The exact result, then one cut
IEEE 754 defines arithmetic in two stages. First the operation is computed as if the exponent range were unbounded and the significand were infinitely wide, producing an exact real value. Then that value is rounded once to the destination format. The single-rounding model is what makes error analysis tractable: for round-to-nearest, every normal result satisfies
$$ \operatorname{fl}(x \circ y) = (x \circ y)(1 + \delta), \qquad |\delta| \le u = 2^{-p} $$
where u is the unit roundoff: 2^-24, about 5.96e-8, for binary32, and 2^-53, about 1.11e-16, for binary64. The guarantee holds only while the result stays in the normal range. Inside the subnormal range the spacing is fixed rather than relative, so the relative bound degrades as the result approaches zero, and the model has to be replaced by an absolute bound of half the smallest subnormal spacing.
The destination significand is p bits wide, so the cut position is determined by the exponent: keep p bits starting at the leading one, and decide from what remains whether to leave those bits alone or add one to the last of them. Everything else in this article is about making that decision correctly with a bounded amount of hardware.
Guard, round, and sticky
Consider adding 1.000…0 × 2^0 to 1.000…01 × 2^-24 in binary32, where p = 24. The second operand must be shifted right by 24 positions to align its radix point with the first. Its leading one moves to bit position 24, one place beyond the 24-bit significand. If the adder kept only the aligned p bits, that one would vanish and the sum would look like an exact 1.0.
Three extra bits below the significand prevent this. They are conventionally named guard, round, and sticky:
- guard holds the first bit shifted out of the significand,
- round holds the second,
- sticky is the OR of every bit shifted out below that.
The sticky bit is the important one. It compresses an arbitrary number of discarded bits into a single bit that answers exactly one question: is the remainder more than zero? Without it, a value like 1.000…0100…01 and a value like 1.000…0100…00 would be indistinguishable after alignment, and the rounding decision, which depends on whether the discarded part is exactly one half or slightly more, would come out wrong.
With the three bits in hand, the decision for round-to-nearest is a small table. If guard is 0, round down. If guard is 1 and either round or sticky is nonzero, the discarded part exceeds one half, so round up. If guard is 1 and both round and sticky are 0, the discarded part is exactly one half, and the tie rule decides.
The hardware cost is a wider adder plus a sticky-OR tree over the shifted-out bits, which grows with the exponent difference. Implementations bound the shift: once the exponent difference exceeds the significand width plus a few bits, the smaller operand cannot affect anything except the sticky bit, so a saturating shifter is enough. That is why adding numbers of wildly different magnitude is not slower than adding numbers of similar magnitude.
Why the tie goes to even
A tie happens when the exact result sits precisely halfway between two representable values. Both choices are equally close, so the rule must be chosen for its statistical and algebraic properties rather than its distance.
Rounding ties away from zero, the rule taught in school, is biased. Every tie moves the result away from zero, so a long sequence of operations that produces ties drifts outward. Rounding ties upward is worse: the drift is one-signed and accumulates linearly in the number of operations. Choosing the neighbour with an even last significand bit splits ties in both directions, because consecutive ties alternate parity.
The rule has a second property that matters more than the statistics. When the result is rounded to even, the low bit of the significand is zero, so the value is exactly representable in a format with one bit less precision. Repeated rounding is therefore idempotent in the common cases: a value already representable in the narrower format survives a round trip through a wider one and back. Round-half-up does not have this property, and neither does round-half-away, which is why both are poor defaults for a system that will round the same quantity more than once.
The same parity rule can be implemented without any floating-point hardware at all, which is a useful check on the mechanism:
/* Round n / 2^k to the nearest integer, ties to even. k >= 0. */
static long round_ties_even(long n, int k)
{
if (k == 0) return n;
long q = n >> k; /* floor division for negative n */
long r = n - (q << k); /* 0 <= r < 2^k */
long half = 1L << (k - 1);
if (r > half || (r == half && (q & 1L))) q += 1;
return q;
}
The condition r == half && (q & 1) is the tie case, and adding one only when q is odd makes the result even. Arithmetic right shift of a negative number rounds toward negative infinity, which is why the remainder is computed as n - (q << k) rather than with a modulo operator.
Directed modes and their error profile
Round-to-nearest is the default, but the standard defines directed modes as well: toward zero, toward positive infinity, and toward negative infinity. They are useful precisely because they are biased. An interval-arithmetic computation run twice, once rounding down and once rounding up, produces a guaranteed enclosure of the exact result, at the cost of doubling the work and widening the interval at every step.
The error profile differs by a factor of two. Round-to-nearest gives |δ| ≤ u; a directed mode gives a one-sided error of up to one ulp, which is 2u in relative terms, and the errors from a chain of operations all point the same way. For a summation of n terms that is a worst case of roughly n·2u·Σ|x_i| instead of the n·u that nearest rounding gives, and in practice the directed bound is tight far more often than the nearest bound is.
There is a fifth rule, ties away from zero, which exists mainly for decimal formats where exact ties are common because decimal inputs have short fractions. Binary formats rarely see a true tie from measured data, so the distinction is mostly visible in conversions.
Double rounding, and why the intermediate format matters
Rounding twice is not the same as rounding once. This is the sharpest practical consequence of the whole mechanism, and it appears whenever a computation is carried out in a wider format and then stored in a narrower one.
Take binary32 as the destination, p = 24. The midpoint between 1 and 1 + 2^-23 is 1 + 2^-24. Now take a real value slightly above that midpoint: 1 + 2^-24 + 2^-60. It needs 61 significant bits. Rounded directly to binary32, it lies above the midpoint, so the result is 1 + 2^-23. Rounded first to binary64, which keeps 53 bits, the 2^-60 term falls below the rounding position and the value becomes exactly 1 + 2^-24, a midpoint. The second rounding then applies the tie rule and returns 1, a full ulp away from the correctly rounded answer.
The condition for the hazard is specific: the first rounding must land exactly on a midpoint of the second format. When the intermediate precision is at least 2p + 2 bits, no double rounding error is possible for the four basic operations and the square root. The inequality is easy to check: binary64 has 53 bits and binary32 has 24, and 53 ≥ 50, so widening a binary32 computation to binary64 and narrowing the result is exact in the sense that matters. binary128 at 113 bits clears the 108 required for binary64. The x87 extended type, with a 64-bit significand, does not clear it for binary64, which is why storing intermediate results in long double and then narrowing is a real source of last-bit differences rather than a hypothetical one.
The standard’s own conversions are specified as single roundings, so the hazard belongs to programs that perform the narrowing explicitly or to language implementations that evaluate in a wider type. Conversions between decimal text and binary are the other place where the single-rounding rule is enforced, and the arithmetic needed to honour it is covered in Correctly Rounded Decimal Conversion and Shortest Round-Trip Printing. A related trick, rounding to odd instead of to even at the intermediate step, removes the hazard entirely: an odd last bit can never be mistaken for a midpoint by the following rounding.
The rounding mode is program state
In C the mode is not an argument to arithmetic; it is a value in the floating-point environment, changed with fesetround from <fenv.h> and read with fegetround. The names are FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD, and FE_DOWNWARD. The mode applies to every operation executed by the thread until it is changed again.
Two failure modes follow. First, the compiler is allowed to assume the default mode unless the translation unit opts in with #pragma STDC FENV_ACCESS ON, so an expression may be constant-folded at compile time using round-to-nearest even though the surrounding code runs under a different mode. Second, most library functions that take a rounding mode (the ones whose names end in _r in Annex F of the C standard) are the only reliable way to obtain correctly rounded results under a non-default mode, because a library implementation may internally use instructions whose behaviour does not follow the dynamic mode.
The mode is also per-thread, and it is not inherited by threads created afterwards in any portable way. Code that sets a mode and then hands work to a thread pool has not set the mode for that pool. Since the choice of mode changes results in the last bit, and since the last bit is what determines whether two runs agree, the mode belongs with the rest of the numerical configuration rather than being set ad hoc at the point of use. What happens when an operation cannot be rounded at all — overflow, underflow, invalid — is a separate mechanism, and the special values that absorb those cases are covered in Subnormals, Signed Zero, and the Cost of Gradual Underflow.
References
- IEEE 754-2019: Standard for Floating-Point Arithmetic — IEEE
- Accuracy and Stability of Numerical Algorithms, 2nd edition — Nicholas J. Higham; SIAM
- Handbook of Floating-Point Arithmetic, 2nd edition — Muller, Brunie, de Dinechin, Jeannerod, Joldes, Lefevre, Melquiond, Revol, Torres; Birkhauser