Fixed-limb rounding #
Two- and four-limb shifts and nearest-even rounding, with guard, sticky, and carry results.
Fixed tuples give these small kernels a statically sized representation. Callers handle exponents
and packing, and LimbRound.Proof relates the operations to natural-number arithmetic.
Increment modulo 2^128, propagating the low-word carry.
Instances For
Compiled code runs UInt128.increment as UInt128.Internal.increment. The two are equal by
rfl.
Set the least-significant bit of a two-limb value.
Instances For
Shift a two-word value right by one bit.
Instances For
Round a two-word value right by one bit using round-to-nearest, ties-to-even.
For a one-bit shift, the quotient is incremented exactly when the two low input bits are 11.
Instances For
Low 64 bits of a right shift by an amount strictly between zero and 64.
Instances For
Round a two-limb value right by shift, returning a single native word.
The kernel is meaningful for 0 < shift < 64 with value.hi < 2^shift, so that the quotient
fits one word, and callers also keep the incremented quotient below 2^64.
roundShiftRightEven_toNat states these hypotheses.
Instances For
Round a two-limb value right by shift using round-to-nearest, ties-to-even, keeping both limbs.
The kernel is meaningful for 0 < shift < 64, the contract of
UInt128.roundShiftRightEven128_toNat.
Instances For
Low 128 bits of a four-word right shift.
Shifts at and beyond 256 return zero. A caller that needs the complete quotient must show that no nonzero bit remains above the returned two-word window. The limb ranges avoid the modulo reduction performed by native machine-word shifts.
Instances For
Test whether any of the lowest width bits of a four-word value is nonzero.
Instances For
Shift right into two words, setting the low bit if any bit below the shift position is nonzero.
When the shifted quotient fits in two words, this is round-to-odd, or sticky, normalization. It preserves nearest-even rounding when the final rounder discards at least two more bits.
For the floating-point formulation, see Sylvie Boldo and Guillaume Melquiond,
"Emulation of a FMA and Correctly Rounded Sums: Proved Algorithms Using Rounding to Odd"
(2008), §III-C, Theorem 3. The fixed-grid statement used here is
FloatLib.Numerics.roundShiftRightEven_shiftRightJam.
Instances For
Number of low bits discarded when reducing a four-limb value to a normalized two-limb value.
Values already below 2^128 use a zero shift. Wider values keep their leading bit at position
127.
Instances For
Normalize a four-limb value into two limbs while jamming every discarded one bit into bit zero.
The result retains the leading 128-bit window, with its low bit ORed with the sticky bit of the discarded suffix. This preserves nearest-even rounding when the final rounder discards at least two more bits.
Instances For
Round a four-limb value right by shift, returning a two-limb result.
The kernel is only valid for 64 < shift < 128, because the discarded field is read from limb1
and limb0 and the halfway marker is built inside limb1. Callers also keep
value.limb3 < 2^(shift - 64) and the incremented quotient below 2^128, so that
shiftRight128 returns the complete quotient. roundShiftRightEven128_toNat states these
hypotheses. Two-word products call this with shifts fracWidth or fracWidth + 1, which
is 112 or 113 for binary128.
Instances For
Bitwise complement of a four-word value.
Instances For
Subtract two four-word values modulo 2^256 by adding the two's complement of the subtrahend.
sub_toNat gives the natural-number difference when the subtrahend is at most the minuend.
Instances For
Compare two four-word values.
Instances For
Set the least-significant bit of a four-word value.
Instances For
Double a four-word value modulo 2^256.
Instances For
Embed a two-word value shifted left by shift < 128 bits into four words. Every shift below 128
is supported, including those UInt256.ofUInt128ShiftedLeft does not cover.