TorchLean API

FloatLib.Kernels.FixedWord.LimbRound.Runtime

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.

@[inline]

Increment modulo 2^128, propagating the low-word carry.

Instances For
    @[inline]

    UInt128.increment with the low-word carry kept as a native word.

    Instances For
      @[inline]

      Set the least-significant bit of a two-limb value.

      Instances For
        @[inline]

        Shift a two-word value right by one bit.

        Instances For
          @[inline]

          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
            @[inline]

            Low 64 bits of a right shift by an amount strictly between zero and 64.

            Instances For
              @[inline]

              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
                @[inline]

                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
                  @[inline]

                  FixedWord.jamCombine on two-word values (UInt128.jamCombine_toNat).

                  Instances For
                    @[inline]

                    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
                      @[inline]

                      Test whether any of the lowest width bits of a four-word value is nonzero.

                      Instances For
                        @[inline]

                        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
                          @[inline]

                          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
                            @[inline]

                            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
                              @[inline]

                              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
                                @[inline]

                                Bitwise complement of a four-word value.

                                Instances For
                                  @[inline]

                                  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
                                    @[inline]

                                    Compare two four-word values.

                                    Instances For
                                      @[inline]

                                      Set the least-significant bit of a four-word value.

                                      Instances For
                                        @[inline]

                                        Double a four-word value modulo 2^256.

                                        Instances For
                                          @[inline]

                                          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.

                                          Instances For