TorchLean API

FloatLib.Numerics.Exact.SignedRat

Exact rationals with an IEEE sign #

A rational number has no negative zero, but every IEEE binary format does. Converting a value through Rat therefore forgets whether a zero was -0 or +0. A cast or mixed-format operation cannot recover that sign from the rational value alone.

SignedRat is a rational together with the sign bit an IEEE format would store for it. For a nonzero value the sign bit is determined by the value, and the structure carries that fact as a proof field, so two SignedRats are equal exactly when their values and sign bits agree. Only a zero has a free sign bit.

The arithmetic operations implement the IEEE sign rules for exact results. A product or quotient has the exclusive-or of the operand signs. An exact zero sum is negative only when both operands are negative, which is the round-to-nearest rule. Callers use addWithCancellationSign to choose the sign of an exact cancellation for directed rounding.

Executable conversion uses this type as the exact domain of every binary destination. Rational sources such as posits and fixed point enter through ofRat, and binary sources decode through ofDyadic, which keeps the dyadic sign.

An exact rational together with the IEEE sign bit of its zero.

negative is the sign bit. For a nonzero value it is forced to decide (value < 0); for zero it distinguishes -0 from +0.

  • value :

    The exact rational value; zero for both signed zeros.

  • negative : Bool

    The IEEE sign bit.

  • negative_eq_of_ne_zero : self.value 0self.negative = decide (self.value < 0)

    A nonzero value determines its sign bit.

Instances For
    Instances For
      theorem FloatLib.Numerics.SignedRat.ext {x y : SignedRat} (hvalue : x.value = y.value) (hnegative : x.negative = y.negative) :
      x = y

      Two signed rationals are equal when their values and sign bits are equal.

      @[inline]

      Numerical equality, ignoring the sign attached to zero.

      Ordinary == remains structural, just like =. Use sameValue only when positive and negative zero should represent the same rational number.

      Instances For
        @[simp]

        sameValue compares exactly the underlying rational values.

        A negative zero prints as -0; every other value prints as its rational value.

        Instances For

          Constructors #

          @[inline]

          The signed rational of a rational; zero receives the positive sign.

          Instances For
            @[simp]

            ofRat keeps the rational value.

            @[simp]

            ofRat marks exactly the negative rationals; zero is positive.

            A nonzero signed rational is recovered from its value alone.

            Negative zero, the value a signed rational adds to Rat.

            Instances For
              @[simp]

              Negative zero has value zero.

              @[simp]

              Negative zero carries the negative sign bit.

              @[simp]

              The zero of SignedRat has value zero.

              @[instance_reducible]

              Both signed-zero representations are mathematical zero for checked exact arithmetic.

              The generic executable zero test recognizes exactly the zero-valued signed rationals.

              Failing the generic zero test means that the rational value is nonzero.

              @[simp]

              The zero of SignedRat is positive zero.

              @[instance_reducible]

              The signed rational of an exact dyadic, keeping the dyadic sign.

              Dyadic.toRat forgets the sign of a zero dyadic; this constructor is the sign-preserving replacement used when a binary format is decoded.

              Instances For
                @[simp]

                ofDyadic keeps the exact rational value of the dyadic.

                @[simp]

                ofDyadic keeps the dyadic sign bit, so a negative dyadic zero stays negative.

                Arithmetic #

                Negation flips the sign bit, including the sign of zero.

                Instances For
                  @[simp]

                  Negation negates the value.

                  @[simp]

                  Negation flips the sign bit, also for zero.

                  Negating a dyadic and then converting agrees with converting and then negating.

                  Exact addition with the round-to-nearest sign rule for an exact zero sum.

                  A nonzero sum takes the sign of its value. A zero sum is negative only when both operands are negative, so -0 + -0 = -0 while x + -x = +0 and -0 + +0 = +0.

                  Instances For
                    @[simp]

                    Addition is exact on values.

                    A nonzero exact sum has the sign of its value.

                    An exact zero sum is negative exactly when both operands are negative.

                    Exact addition with a caller-selected sign for cancellation between opposite signs.

                    Set negativeCancellation for rounding toward negative infinity. Same-sign zeros keep their sign in either mode: +0 + +0 = +0 and -0 + -0 = -0. A nonzero sum always takes the sign of its rational value.

                    Instances For
                      @[simp]
                      theorem FloatLib.Numerics.SignedRat.value_addWithCancellationSign (negativeCancellation : Bool) (x y : SignedRat) :
                      (addWithCancellationSign negativeCancellation x y).value = x.value + y.value

                      Choosing a cancellation sign leaves the exact rational sum unchanged.

                      @[simp]

                      Positive cancellation uses the ordinary round-to-nearest signed-rational addition.

                      theorem FloatLib.Numerics.SignedRat.negative_addWithCancellationSign_of_ne_zero (negativeCancellation : Bool) {x y : SignedRat} (hsum : x.value + y.value 0) :
                      (addWithCancellationSign negativeCancellation x y).negative = decide (x.value + y.value < 0)

                      A nonzero sum has its numerical sign, independent of the cancellation policy.

                      theorem FloatLib.Numerics.SignedRat.negative_addWithCancellationSign_of_eq_zero (negativeCancellation : Bool) {x y : SignedRat} (hsum : x.value + y.value = 0) :
                      (addWithCancellationSign negativeCancellation x y).negative = if negativeCancellation = true then x.negative || y.negative else x.negative && y.negative

                      An exact zero sum follows the selected direction while preserving same-sign zeros.

                      Subtraction is addition of the negation, as in IEEE 754.

                      Instances For
                        @[simp]

                        Subtraction is exact on values.

                        Exact multiplication; the sign bit is the exclusive-or of the operand sign bits.

                        Instances For
                          @[simp]

                          Multiplication is exact on values.

                          @[simp]

                          A product takes the exclusive-or of the operand signs, the IEEE rule for exact products.

                          Exact division; the sign bit is the exclusive-or of the operand sign bits.

                          Division by a zero value returns a zero value, following Rat; callers reject zero divisors before quantizing.

                          Instances For
                            @[simp]

                            Division is exact on values, with Rat division by zero giving zero.

                            @[simp]

                            A quotient takes the exclusive-or of the operand signs, the IEEE rule for exact quotients.