Magnitude rounding rules #
Rounding a signed value to a binary grid reduces, once its sign is known, to rounding a nonnegative magnitude to one of the two integers around it. Four rules cover the IEEE 754 rounding directions and MPFR's rounding away from zero: truncation, rounding up, and the two nearest rules, which differ only at an exact tie.
MagnitudeRounding names the four rules, and MagnitudeRounding.increment decides each of them
from the three rounding bits: the least retained bit, the guard bit, and the sticky bit.
roundShiftRight applies a rule to a division by a power of two and roundQuotient to a division
by any natural number. Their nearest-even rules call roundShiftRightEven and
roundQuotientEven, so each division keeps one nearest-even implementation. The other rules use
shifts in roundShiftRight and a single division in roundQuotient.
The @[csimp] machine-word replacements of roundShiftRightEven and roundQuotientEven apply
where those functions are called by name. A call through roundShiftRight or roundQuotient is
compiled from the definitions here, where those replacements are not yet registered, so it runs
the arbitrary-precision definition.
The theorems give each rule in guard-and-sticky form, relate the shift and quotient forms, express nearest-away as nearest-even with ties sent to the ceiling, and read the ternary value (whether the delivered value is below, equal to, or above the exact one) off the rounding bits.
Rule for rounding a nonnegative quotient to one of the two integers around it.
- down : MagnitudeRounding
Keep the integer part.
- up : MagnitudeRounding
Take the next integer whenever the quotient is not an integer.
- nearestEven : MagnitudeRounding
Take the nearer integer, and the even one at an exact tie.
- nearestAway : MagnitudeRounding
Take the nearer integer, and the larger one at an exact tie.
Instances For
Instances For
Whether rule adds one to the truncated quotient.
lsb is the least significant retained bit, guard the most significant discarded bit, and
sticky whether any discarded bit below the guard bit is set. When neither guard nor sticky
is set the quotient is exact and no rule increments it.
Instances For
No rule increments an exact quotient.
Shift rounding #
⌈value / 2^shift⌉ for natural numbers.
One shift gives the truncated quotient, and shifting it back decides whether a nonzero remainder carries the result to the next integer.
Instances For
Whether the bits that a right shift by shift discards are exactly one half of a retained unit.
That is the case when the guard bit is set and every lower discarded bit is clear. A clear guard
bit settles the answer before any remainder is formed, so a shift far beyond the width of value
costs one shift.
Instances For
Round value / 2^shift to an integer under rule.
Truncation is a right shift and rounding up is shiftRightCeil. Nearest-even is
roundShiftRightEven, run through its arbitrary-precision definition. Nearest-away keeps the guard
bit in a first shift, adds one, and drops it in a second, so the guard bit alone decides. A zero
shift returns value under every rule.
Instances For
Quotient rounding #
Round numerator / denominator to an integer under rule.
Nearest-even is roundQuotientEven, again through its arbitrary-precision definition. The other
rules use one division each: rounding up divides numerator - 1, and nearest-away divides
2 * numerator + denominator by 2 * denominator.
A zero denominator has no quotient. Truncation, rounding up, and nearest-away return 0 there.
Nearest-even keeps the convention of roundQuotientEven, which returns 0 for a zero numerator and
1 otherwise.
Instances For
Unfolding lemmas #
Truncating shift rounding is a right shift.
Upward shift rounding is shiftRightCeil.
Nearest-even shift rounding is roundShiftRightEven.
Truncating quotient rounding is natural division.
Nearest-even quotient rounding is roundQuotientEven.
A ceiling shift by zero returns its argument.
A zero shift is exact under every rule.
Rounding up with a zero denominator returns zero.
Nearest-away rounding with a zero denominator returns zero.
A denominator of one is exact under every rule.
Rounding bits #
A shift by a positive amount is inexact exactly when its guard bit or its sticky bit is set.
Every rule in guard-and-sticky form.
For a positive shift, the rounded value is the truncated quotient, plus one exactly when the rule
increments it given the least retained bit value.testBit shift, the guard bit
value.testBit (shift - 1), and the sticky bit value % 2^(shift - 1) ≠ 0.
Rounding up is the ceiling of the quotient: the truncated quotient when the remainder is zero and
its successor otherwise, with 0 for a zero denominator.
Nearest-away quotient rounding with a nonzero denominator increments the truncated quotient exactly when twice the remainder reaches the denominator.
Nearest-away quotient rounding exceeds a bound exactly when the quotient reaches the bound plus one half.
Nearest-away quotient rounding is nearest-even rounding with an exact tie sent up.
With a nonzero denominator the two rules differ only when twice the remainder equals the denominator, where nearest-away always takes the larger integer.
Whether a quotient is an exact tie depends only on the rational it represents.
Two quotients with nonzero denominators and equal cross products are ties together: twice the remainder equals the denominator for both or for neither.
Shift rounding under every rule is quotient rounding by the corresponding power of two.
Nearest-away shift rounding is nearest-even shift rounding with an exact tie sent to the ceiling.
Ternary value #
Compare a shift-rounded magnitude, scaled back, with the exact magnitude.
The result is equal exactly when no guard or sticky bit is set. Otherwise it is above the exact magnitude when the rule increments the truncated quotient and below it when the rule truncates.
The ternary value of a signed shift rounding, read off its rounding bits.
For a negative value both the delivered and the exact value change sign, so their comparison is the magnitude comparison swapped. The delivered value equals the exact one when no guard or sticky bit is set. Otherwise it is above the exact value exactly when the increment decision differs from the sign: incrementing a positive magnitude, or truncating a negative one.