Documentation

Hale.Base.Data.Fixed

structure Data.Fixed (precision : Nat) :

A fixed-point decimal number with precision decimal places.

The underlying representation is a scaled integer: $$\text{Fixed}_p(v) \equiv v \times 10^{-p}$$

The precision $p$ is a type parameter, so Fixed 2 $\neq$ Fixed 4. This prevents accidental mixing of different precisions at compile time.

For example, Fixed 2 represents values like $3.14$ (stored as $314$).

  • raw : Int

    The raw scaled integer. The actual value is $\text{raw} \times 10^{-\text{precision}}$.

Instances For
    def Data.instBEqFixed.beq {precision✝ : Nat} :
    Fixed precision✝Fixed precision✝Bool
    Equations
    Instances For
      @[implicit_reducible]
      instance Data.instBEqFixed {precision✝ : Nat} :
      BEq (Fixed precision✝)
      Equations
      def Data.instOrdFixed.ord {precision✝ : Nat} :
      Fixed precision✝Fixed precision✝Ordering
      Equations
      Instances For
        @[implicit_reducible]
        instance Data.instOrdFixed {precision✝ : Nat} :
        Ord (Fixed precision✝)
        Equations
        def Data.instReprFixed.repr {precision✝ : Nat} :
        Fixed precision✝NatStd.Format
        Equations
        Instances For
          @[implicit_reducible]
          instance Data.instReprFixed {precision✝ : Nat} :
          Repr (Fixed precision✝)
          Equations
          @[implicit_reducible]
          instance Data.instHashableFixed {precision✝ : Nat} :
          Hashable (Fixed precision✝)
          Equations
          def Data.instHashableFixed.hash {precision✝ : Nat} :
          Fixed precision✝UInt64
          Equations
          Instances For

            Compute $10^n$ as a natural number. Helper for scaling operations. $$\text{scale}(p) = 10^p$$

            Equations
            Instances For
              theorem Data.Fixed.scale_pos (p : Nat) :
              scale p > 0

              Proof that $10^p > 0$ for any $p$.

              @[inline]
              def Data.Fixed.fromInt {p : Nat} (n : Int) :

              Create a Fixed from an integer (no fractional part). $$\text{fromInt}(n) = n \times 10^p \times 10^{-p} = n$$

              Equations
              Instances For
                @[implicit_reducible]
                instance Data.Fixed.instAdd {p : Nat} :

                Addition of fixed-point numbers (exact, no precision loss): $$\text{Fixed}_p(a) + \text{Fixed}_p(b) = \text{Fixed}_p(a + b)$$

                Equations
                @[implicit_reducible]
                instance Data.Fixed.instSub {p : Nat} :

                Subtraction of fixed-point numbers (exact, no precision loss): $$\text{Fixed}_p(a) - \text{Fixed}_p(b) = \text{Fixed}_p(a - b)$$

                Equations
                @[implicit_reducible]
                instance Data.Fixed.instNeg {p : Nat} :

                Negation: $-\text{Fixed}_p(a) = \text{Fixed}_p(-a)$.

                Equations
                @[implicit_reducible]
                instance Data.Fixed.instMul {p : Nat} :

                Multiplication scales by $10^{-p}$ to maintain precision: $$\text{Fixed}_p(a) \times \text{Fixed}_p(b) = \text{Fixed}_p\!\left(\left\lfloor \frac{a \cdot b}{10^p} \right\rfloor\right)$$

                Note: multiplication may lose precision in the last digit due to truncation.

                Equations
                @[implicit_reducible]
                Equations
                @[implicit_reducible]
                Equations
                @[implicit_reducible]
                Equations
                @[implicit_reducible]
                Equations
                • One or more equations did not get rendered due to their size.
                theorem Data.Fixed.add_exact {p : Nat} (a b : Fixed p) :
                (a + b).raw = a.raw + b.raw

                Addition is exact: adding two fixed-point values and converting to ratio equals converting each to ratio and adding.

                $$\text{toRatio}(a + b) = \text{toRatio}(a) + \text{toRatio}(b)$$

                This is the key advantage of fixed-point over floating-point: addition introduces no rounding error.

                theorem Data.Fixed.sub_exact {p : Nat} (a b : Fixed p) :
                (a - b).raw = a.raw - b.raw

                Subtraction is also exact: $$\text{toRatio}(a - b) = \text{toRatio}(a) - \text{toRatio}(b)$$

                theorem Data.Fixed.neg_neg {p : Nat} (a : Fixed p) :
                - -a = a

                Double negation: $-(-a) = a$.

                theorem Data.Fixed.fromInt_zero {p : Nat} :
                (fromInt 0).raw = 0

                fromInt 0 yields zero raw value when precision is nonzero.

                def Data.Fixed.toRatio {p : Nat} (f : Fixed p) :

                Convert to a Ratio preserving the exact value: $$\text{toRatio}(\text{Fixed}_p(v)) = \frac{v}{10^p}$$

                Equations
                Instances For