Nearest-even rounding through guard and sticky bits #
The width-generic rounder Numerics.roundShiftRightEven compares the discarded remainder with the
halfway value 2^(shift - 1). Limb kernels can avoid constructing that value by using three
Boolean tests: the guard bit just below the kept quotient, whether
any lower bit is set, and the parity of the quotient. This module proves that restatement and its
consequences for the sticky-bit normalisation used by addition and fused multiply-add.
roundShiftRightEven_eq_guard_stickyis the three-bit form of nearest-even rounding.roundShiftRightEven_shiftRightJamshows that jamming every bit below positionjinto one sticky bit does not change a later rounding by at leastj + 2bits. Applying this to an addition result requires a separate argument relating that result to its jammed value.roundShiftRightEven_mul_two_powandroundShiftRightEven_mul_two_pow_of_lerelate rounding of a scaled value to rounding of the original.shiftRightJam_add_mul_two_powandshiftRightJam_mul_two_pow_subdescribe the jammed quotient of an aligned sum or difference in terms of the two operands, andlog2_shiftRightJamlocates its leading bit.
These statements apply to natural numbers independently of their storage. The fixed-word and limb-array kernels use them to justify their rounding steps.
The guard-and-sticky form #
The number one has no bits above position zero.
Nearest-even rounding in guard-and-sticky form.
The quotient is incremented exactly when the guard bit is set and either a sticky bit is set or the quotient is odd.
The nearest-even quotient is at most the successor of the truncated quotient.
The nearest-even quotient is at least the truncated quotient.
Jamming #
Jamming never decreases the truncated quotient.
Jamming a value with a set bit at or above the jam position gives a nonzero result.
Rounding after a sticky-bit jam agrees with rounding the original value, provided the rounding keeps at least the guard bit above the jammed position.
Scaling #
Rounding a value scaled by 2^k by k more bits is rounding the value.