TorchLean API

FloatLib.Floats.Formats.DecimalInterchange.Algebraic.Proof

Numerical guarantees for decimal algebraic operations #

The bounds compare delivered values with the exact square, integer power, reciprocal square root, or hypotenuse. They hold for arbitrary decimal formats. The one-unit bounds cover all five rounding modes; nearest modes satisfy the half-unit bound. Overflow is excluded explicitly, as in the underlying rounders.

theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.powInt_eq_project (f : Format) (mode : RoundingMode) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) (n : ℤ) (ha : a ≠ 0 ∨ 0 ≤ n) :
∃ (preferred : ℤ) (negativeZero : Bool), powInt f mode x n = project f mode (a ^ n) preferred negativeZero

A finite integer power is exactly one rational projection whenever it has no pole.

theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.rsqrt_eq_sqrtMagnitude (f : Format) (mode : RoundingMode) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) (ha : 0 < a) :
∃ (preferred : ℤ), rsqrt f mode x = sqrtMagnitude f mode a⁻¹ preferred

Positive finite reciprocal square root uses the exact reciprocal as its radicand.

theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.hypot_eq_sqrtMagnitude (f : Format) (mode : RoundingMode) (x y : Datum) (a b : ℚ) (hx : x.toRat? = some a) (hy : y.toRat? = some b) :
∃ (preferred : ℤ), hypot f mode x y = sqrtMagnitude f mode (a ^ 2 + b ^ 2) preferred

Hypotenuse uses an unrounded sum of squares, including when both operands are zero.

theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.square_eq_project (f : Format) (mode : RoundingMode) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) :
∃ (preferred : ℤ), square f mode x = project f mode (a ^ 2) preferred
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.square_error_le_half (f : Format) (mode : RoundingMode) (hm : mode = RoundingMode.nearestEven ∨ mode = RoundingMode.nearestAway) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) (hfinite : (square f mode x).status.overflow = false) :
∃ (value : ℚ), (square f mode x).value.toRat? = some value ∧ |value - a ^ 2| ≤ 10 ^ roundingQuantum f |a ^ 2| / 2
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.square_error_lt_one (f : Format) (mode : RoundingMode) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) (hfinite : (square f mode x).status.overflow = false) :
∃ (value : ℚ), (square f mode x).value.toRat? = some value ∧ |value - a ^ 2| < 10 ^ roundingQuantum f |a ^ 2|
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.square_inexact_iff (f : Format) (mode : RoundingMode) (x : Datum) (a value : ℚ) (hx : x.toRat? = some a) (hfinite : (square f mode x).status.overflow = false) (hv : (square f mode x).value.toRat? = some value) :
(square f mode x).status.inexact = true ↔ value ≠ a ^ 2
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.powInt_error_le_half (f : Format) (mode : RoundingMode) (hm : mode = RoundingMode.nearestEven ∨ mode = RoundingMode.nearestAway) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) (n : ℤ) (ha : a ≠ 0 ∨ 0 ≤ n) (hfinite : (powInt f mode x n).status.overflow = false) :
∃ (value : ℚ), (powInt f mode x n).value.toRat? = some value ∧ |value - a ^ n| ≤ 10 ^ roundingQuantum f |a ^ n| / 2
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.powInt_error_lt_one (f : Format) (mode : RoundingMode) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) (n : ℤ) (ha : a ≠ 0 ∨ 0 ≤ n) (hfinite : (powInt f mode x n).status.overflow = false) :
∃ (value : ℚ), (powInt f mode x n).value.toRat? = some value ∧ |value - a ^ n| < 10 ^ roundingQuantum f |a ^ n|
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.powInt_inexact_iff (f : Format) (mode : RoundingMode) (x : Datum) (a value : ℚ) (hx : x.toRat? = some a) (n : ℤ) (ha : a ≠ 0 ∨ 0 ≤ n) (hfinite : (powInt f mode x n).status.overflow = false) (hv : (powInt f mode x n).value.toRat? = some value) :
(powInt f mode x n).status.inexact = true ↔ value ≠ a ^ n
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.powInt_underflow_iff (f : Format) (mode : RoundingMode) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) (n : ℤ) (ha : a ≠ 0 ∨ 0 ≤ n) (hfinite : (powInt f mode x n).status.overflow = false) :
(powInt f mode x n).status.underflow = true ↔ |a ^ n| < f.minNormal ∧ (powInt f mode x n).status.inexact = true
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.rsqrt_error_le_half (f : Format) (mode : RoundingMode) (hm : mode = RoundingMode.nearestEven ∨ mode = RoundingMode.nearestAway) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) (ha : 0 < a) (hfinite : (rsqrt f mode x).status.overflow = false) :
∃ (value : ℚ), (rsqrt f mode x).value.toRat? = some value ∧ |↑value - (√↑a)⁻¹| ≤ 10 ^ sqrtQuantum f a⁻¹ / 2
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.rsqrt_error_lt_one (f : Format) (mode : RoundingMode) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) (ha : 0 < a) (hfinite : (rsqrt f mode x).status.overflow = false) :
∃ (value : ℚ), (rsqrt f mode x).value.toRat? = some value ∧ |↑value - (√↑a)⁻¹| < 10 ^ sqrtQuantum f a⁻¹
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.hypot_error_le_half (f : Format) (mode : RoundingMode) (hm : mode = RoundingMode.nearestEven ∨ mode = RoundingMode.nearestAway) (x y : Datum) (a b : ℚ) (hx : x.toRat? = some a) (hy : y.toRat? = some b) (hfinite : (hypot f mode x y).status.overflow = false) :
∃ (value : ℚ), (hypot f mode x y).value.toRat? = some value ∧ |↑value - √(↑a ^ 2 + ↑b ^ 2)| ≤ 10 ^ sqrtQuantum f (a ^ 2 + b ^ 2) / 2
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.hypot_error_lt_one (f : Format) (mode : RoundingMode) (x y : Datum) (a b : ℚ) (hx : x.toRat? = some a) (hy : y.toRat? = some b) (hfinite : (hypot f mode x y).status.overflow = false) :
∃ (value : ℚ), (hypot f mode x y).value.toRat? = some value ∧ |↑value - √(↑a ^ 2 + ↑b ^ 2)| < 10 ^ sqrtQuantum f (a ^ 2 + b ^ 2)
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.rsqrt_inexact_iff (f : Format) (mode : RoundingMode) (x : Datum) (a value : ℚ) (hx : x.toRat? = some a) (ha : 0 < a) (hfinite : (rsqrt f mode x).status.overflow = false) (hv : (rsqrt f mode x).value.toRat? = some value) :
(rsqrt f mode x).status.inexact = true ↔ ↑value ≠ (√↑a)⁻¹
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.hypot_inexact_iff (f : Format) (mode : RoundingMode) (x y : Datum) (a b value : ℚ) (hx : x.toRat? = some a) (hy : y.toRat? = some b) (hfinite : (hypot f mode x y).status.overflow = false) (hv : (hypot f mode x y).value.toRat? = some value) :
(hypot f mode x y).status.inexact = true ↔ ↑value ≠ √(↑a ^ 2 + ↑b ^ 2)
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.hypot_underflow_iff (f : Format) (mode : RoundingMode) (x y : Datum) (a b : ℚ) (hx : x.toRat? = some a) (hy : y.toRat? = some b) (hfinite : (hypot f mode x y).status.overflow = false) :
(hypot f mode x y).status.underflow = true ↔ √(↑a ^ 2 + ↑b ^ 2) < ↑f.minNormal ∧ (hypot f mode x y).status.inexact = true
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.rsqrt_directed_le (f : Format) (mode : RoundingMode) (hm : mode = RoundingMode.towardZero ∨ mode = RoundingMode.towardNegative) (x : Datum) (a : ℚ) (hx : x.toRat? = some a) (ha : 0 < a) (hfinite : (rsqrt f mode x).status.overflow = false) :
∃ (value : ℚ), (rsqrt f mode x).value.toRat? = some value ∧ ↑value ≤ (√↑a)⁻¹
theorem FloatLib.Floats.Formats.DecimalInterchange.Arithmetic.hypot_directed_le (f : Format) (mode : RoundingMode) (hm : mode = RoundingMode.towardZero ∨ mode = RoundingMode.towardNegative) (x y : Datum) (a b : ℚ) (hx : x.toRat? = some a) (hy : y.toRat? = some b) (hfinite : (hypot f mode x y).status.overflow = false) :
∃ (value : ℚ), (hypot f mode x y).value.toRat? = some value ∧ ↑value ≤ √(↑a ^ 2 + ↑b ^ 2)