### Division examples Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Examples demonstrating exact and inexact division results. ```elixir iex> FastDecimal.div(FastDecimal.new("10"), FastDecimal.new("2")) %FastDecimal{coef: 5, exp: 0} iex> FastDecimal.div(FastDecimal.new("1"), FastDecimal.new("2")) %FastDecimal{coef: 5, exp: -1} iex> FastDecimal.div(FastDecimal.new("10.0"), FastDecimal.new("2")) %FastDecimal{coef: 50, exp: -1} ``` ```elixir iex> FastDecimal.div(FastDecimal.new("10"), FastDecimal.new("3"), precision: 5) %FastDecimal{coef: 33333, exp: -4} ``` -------------------------------- ### Compare Decimal version parsing behavior Source: https://hexdocs.pm/fastdecimal/migration.html Examples showing how Decimal v2.4 and v3.0+ handle parsing limits compared to FastDecimal's approach. ```elixir # decimal v2.4 (opt-in): Decimal.parse("1e1000", max_exponent: 100) # → :error Decimal.cast(input, max_digits: 50) # → :error if too long # decimal v3.0+ (rejected by default): Decimal.parse("1.012345678901234567890123456789012345") # → :error (35 sig digits > 34) Decimal.parse("1e7000") # → :error (exp > 6144) Decimal.new("1e7000", max_exponent: :infinity) # explicit opt-out ``` -------------------------------- ### Exact division representation changes Source: https://hexdocs.pm/fastdecimal/changelog.html Examples showing the transition from un-reduced coefficients to GDA ideal exponent forms for exact division results. ```elixir div(10, 2) → %FastDecimal{coef: 5, exp: 0} (was coef: 5×10^27) div(1, 2) → %FastDecimal{coef: 5, exp: -1} div("10.0", 2) → %FastDecimal{coef: 50, exp: -1} ("5.0", like Decimal) div(0, 3) → %FastDecimal{coef: 0, exp: 0} (was {0, -28}) ``` -------------------------------- ### Run Benchmarks and Tests Source: https://hexdocs.pm/fastdecimal/index.html Commands to execute the test suite and various benchmark scripts for performance analysis. ```bash mix deps.get mix test # 19 doctests + 41 properties + 325 unit tests = 385 total mix bench # → bench/summary.exs (headline table, ~1 minute) mix bench.all # → every bench file end-to-end (~20 minutes) # Or run a specific bench: mix run bench/division.exs # div / div_int / div_rem / rem mix run bench/rounding.exs # round/3 × 7 modes mix run bench/sqrt.exs # sqrt at 6 precisions mix run bench/conversion.exs # to_string formats, cast, to_int/float mix run bench/special_values.exs # NaN/Inf overhead mix run bench/realistic.exs # fintech-style workloads mix run bench/batch.exs # sum/product at 4 list sizes mix run bench/profile.exs # per-op time + alloc + reductions mix run bench/parse.exs # parser strategy shootout mix run bench/representation.exs # struct vs raw tuple mix run bench/targeted.exs # parse / compare-large-gap / normalize-multi-zero / to_integer / div fast paths mix run bench/disasm.exs # BEAM bytecode dump ``` -------------------------------- ### Run performance benchmarks Source: https://hexdocs.pm/fastdecimal/index.html Command to execute the library's internal benchmark suite. ```bash mix bench ``` -------------------------------- ### Assess migration complexity via grep Source: https://hexdocs.pm/fastdecimal/migration.html Run these commands in your project root to identify usage of features that differ between decimal and FastDecimal. ```bash # 1. Do you use Decimal.Context.set / with / get / update? grep -rn "Decimal.Context" lib/ test/ # 2. Do you have %Decimal{...} struct literals (constructing or pattern matching)? grep -rn "%Decimal{" lib/ test/ # 3. Do you depend on signaling NaN (sNaN) vs quiet NaN distinction? grep -rn ":sNaN\|signaling" lib/ # 4. Do you read Decimal.Context flags after operations? grep -rn "Decimal.Context.*flags\|\.flags" lib/ test/ # 5. Do you depend on -0 being distinguishable from 0? grep -rn "Decimal.new(\"-0\")" lib/ test/ ``` -------------------------------- ### Migrate Pricing Module to FastDecimal Source: https://hexdocs.pm/fastdecimal/migration.html Shows the minimal change required to migrate a module by aliasing FastDecimal.Compat as Decimal. ```elixir defmodule Pricing do def apply_fee(price, fee_bps) do Decimal.mult(price, Decimal.add(Decimal.div(fee_bps, 10_000), 1)) end def spread(bid, ask) do diff = Decimal.sub(ask, bid) mean = Decimal.add(ask, bid) |> Decimal.div(2) diff |> Decimal.div(mean) |> Decimal.mult(10_000) |> Decimal.round(4) end end ``` ```elixir defmodule Pricing do + alias FastDecimal.Compat, as: Decimal def apply_fee(price, fee_bps) do Decimal.mult(price, Decimal.add(Decimal.div(fee_bps, 10_000), 1)) end def spread(bid, ask) do diff = Decimal.sub(ask, bid) mean = Decimal.add(ask, bid) |> Decimal.div(2) diff |> Decimal.div(mean) |> Decimal.mult(10_000) |> Decimal.round(4) end end ``` -------------------------------- ### Perform arithmetic operations with FastDecimal Source: https://hexdocs.pm/fastdecimal/index.html Demonstrates basic arithmetic, summation, rounding, and precision-controlled division using the FastDecimal sigil and module functions. ```elixir import FastDecimal ~d"1.23" |> FastDecimal.add(~d"4.567") |> FastDecimal.mult(~d"2") |> FastDecimal.to_string() # => "11.594" FastDecimal.sum([~d"1.5", ~d"2.5", ~d"3"]) # => ~d"7.0" FastDecimal.round(~d"1.236", 2) # ~d"1.24" FastDecimal.sqrt(~d"2", precision: 10) # ~d"1.414213562" FastDecimal.div(~d"10", ~d"3", precision: 5) # ~d"3.3333" ``` -------------------------------- ### Create new decimal from components Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Decimal-style 3-arg constructor: sign (1 or -1), coef, exp. ```elixir @spec new(1 | -1, non_neg_integer(), integer()) :: FastDecimal.t() ``` -------------------------------- ### FastDecimal.Compat Functions Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html A collection of functions for decimal arithmetic, comparison, and creation. ```APIDOC ## integer?(d) Checks if the provided input is an integer. ## lt?(a, b) Compares two inputs and returns true if the first is less than the second. ## max(a, b) Returns the maximum of two decimal inputs. ## min(a, b) Returns the minimum of two decimal inputs. ## minus(a) Returns the negation of the input decimal. ## mult(a, b) Multiplies two decimal inputs. ## multiply(a, b) Alias for mult/2. ## nan() Returns a NaN (Not a Number) decimal value. ## nan?(a) Checks if the input is NaN. ## neg_inf() Returns a negative infinity decimal value. ## negate(a) Alias for minus/1. ## negative?(a) Checks if the input is negative. ## new(input) Creates a new decimal from the given input. ## new(sign, coef, exp) Creates a new decimal using sign (1 or -1), coefficient, and exponent. ## normalize(a) Normalizes the decimal value. ## plus(a) Returns the positive value of the input. ## positive?(a) Checks if the input is positive. ## reduce(a) Alias for normalize/1. ## rem(a, b) Calculates the remainder of two decimal inputs. ``` -------------------------------- ### Migrating to FastDecimal.Compat Source: https://hexdocs.pm/fastdecimal/index.html Use the FastDecimal.Compat module to mirror the decimal library's public surface while auto-coercing various input types. ```elixir defmodule MyLedger do alias FastDecimal.Compat, as: Decimal # add this line, rest stays the same def total(items) do Enum.reduce(items, Decimal.new(0), fn item, acc -> Decimal.add(acc, item.amount) end) end end ``` -------------------------------- ### product(list) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Calculates the product of a list of FastDecimals. ```APIDOC ## product([t()]) ### Description Product of a list of FastDecimals. ### Signature `@spec product([t()]) :: t()` ``` -------------------------------- ### Use is_decimal guard macro Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Demonstrates using the is_decimal guard-safe predicate within a module. ```elixir defmodule MyMod do require FastDecimal def total(d) when FastDecimal.is_decimal(d) do # ... end end ``` -------------------------------- ### Constructing FastDecimal values Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Create new decimal instances using string parsing or explicit coefficient and exponent arguments. ```elixir iex> FastDecimal.new("1.23") %FastDecimal{coef: 123, exp: -2} iex> FastDecimal.new(123, -2) %FastDecimal{coef: 123, exp: -2} ``` -------------------------------- ### Apply the FastDecimal Compat shim Source: https://hexdocs.pm/fastdecimal/migration.html Use the Compat module to alias FastDecimal as Decimal, allowing existing code to route through the shim. ```elixir defmodule MyApp.Ledger do + alias FastDecimal.Compat, as: Decimal def total(items) do Enum.reduce(items, Decimal.new(0), fn item, acc -> Decimal.add(acc, item.amount) end) end def round_to_cents(d), do: Decimal.round(d, 2, :half_even) end ``` -------------------------------- ### Benchmark workload performance with Benchee Source: https://hexdocs.pm/fastdecimal/migration.html Use this snippet in a test or iex session to compare the performance of your existing decimal-based code against the new FastDecimal implementation. ```elixir Benchee.run(%{ "before (decimal)" => fn -> my_workload_using_decimal() end, "after (fastdecimal)" => fn -> my_workload_using_fastdecimal() end }, time: 5, warmup: 2) ``` -------------------------------- ### new(int) / new(coef, exp) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Creates a new FastDecimal instance from an integer/string or coefficient and exponent. ```APIDOC ## new(String.t() | integer()) ### Description Creates a new FastDecimal from a string or integer. ### Signature `@spec new(String.t() | integer()) :: t()` ## new(integer(), integer()) ### Description Creates a new FastDecimal from a coefficient and exponent. ### Signature `@spec new(integer(), integer()) :: t()` ``` -------------------------------- ### Construct FastDecimal values Source: https://hexdocs.pm/fastdecimal/index.html Create decimal values using sigils, runtime parsing, or direct conversion from other types. ```elixir import FastDecimal ~d"1.23" # Compile-time literal (zero parse cost at runtime) ~d"1.23e10" # Scientific notation ~d"Infinity" # +∞ ~d"-Inf" # -∞ ~d"NaN" # NaN FastDecimal.new("1.23") # Runtime parse, raises on bad input FastDecimal.new(42) # From integer FastDecimal.new(123, -2) # From coef + exp FastDecimal.parse("1.23") # {:ok, t} | :error — no raise FastDecimal.cast(value) # Soft parse, accepts FastDecimal/Decimal/int/string/float/nil ``` -------------------------------- ### Comparison and predicates Source: https://hexdocs.pm/fastdecimal/index.html Compare decimal values or check their properties. ```elixir FastDecimal.compare(a, b) # :lt | :eq | :gt | :nan FastDecimal.equal?(a, b) FastDecimal.lt?(a, b) ; FastDecimal.gt?(a, b) FastDecimal.min(a, b) ; FastDecimal.max(a, b) FastDecimal.zero?(d) ; FastDecimal.positive?(d) ; FastDecimal.negative?(d) FastDecimal.nan?(d) ; FastDecimal.inf?(d) ; FastDecimal.finite?(d) ``` -------------------------------- ### Refactor pattern matching and construction Source: https://hexdocs.pm/fastdecimal/migration.html Replace struct pattern matching with predicate functions and use the 3-arg constructor for manual struct creation. ```elixir # Before: case decimal do %Decimal{sign: -1} -> :negative %Decimal{sign: 1, coef: 0} -> :zero %Decimal{} -> :positive end # After: use predicates instead of pattern matching internals cond do Decimal.negative?(decimal) -> :negative Decimal.zero?(decimal) -> :zero true -> :positive end ``` ```elixir # Before: %Decimal{sign: 1, coef: 123, exp: -2} %Decimal{sign: -1, coef: 50, exp: -1} # After: use the shimmed 3-arg constructor Decimal.new(1, 123, -2) Decimal.new(-1, 50, -1) ``` -------------------------------- ### Create new FastDecimal from coefficient and exponent Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Constructs a new FastDecimal using explicit coefficient and exponent values. ```elixir @spec new(integer(), integer()) :: t() ``` -------------------------------- ### FastDecimal.Compat API Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html The FastDecimal.Compat module provides a set of functions that mirror the standard Decimal library API, allowing for easy migration by aliasing the module. ```APIDOC ## Functions ### abs(a) Returns the absolute value of the input. ### add(a, b) Adds two decimal values. ### cast(value) Soft constructor that returns `{:ok, t} | :error`. Mirrors Ecto.Type.cast/1 behavior. ### div(a, b, opts \\ []) Performs division. Defaults to precision 28. Accepts `precision` and `rounding` options. ### new(input) Creates a new decimal from the provided input. ### new(arg1, coef, exp) Decimal-style 3-arg constructor: sign (1 or -1), coefficient, and exponent. ### round(a, places \\ 0, mode \\ :half_up) Rounds the decimal value to the specified number of places using the given rounding mode. ### sqrt(a, opts \\ []) Calculates the square root of the decimal value. ``` -------------------------------- ### Create new decimal Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Constructs a new FastDecimal from the input. ```elixir @spec new(input()) :: FastDecimal.t() ``` -------------------------------- ### Add FastDecimal Dependency Source: https://hexdocs.pm/fastdecimal/migration.html Add the FastDecimal dependency to your mix.exs file alongside the existing decimal library. ```elixir {:fastdecimal, "~> 1.0"} ``` -------------------------------- ### Define to_string_format type Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Supported output formats for string conversion. ```elixir @type to_string_format() :: :normal | :scientific | :raw | :xsd ``` -------------------------------- ### Using the ~d sigil Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Define decimal literals at compile-time to avoid runtime parsing costs. ```elixir import FastDecimal ~d"1.23" # => %FastDecimal{coef: 123, exp: -2} ``` -------------------------------- ### Use guard-safe macros Source: https://hexdocs.pm/fastdecimal/index.html Use the provided macro for guard-safe type checking. ```elixir require FastDecimal def process(d) when FastDecimal.is_decimal(d), do: ... ``` -------------------------------- ### Compare values for less than Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Checks if the first value is less than the second. ```elixir @spec lt?(input(), input()) :: boolean() ``` -------------------------------- ### Add FastDecimal dependency Source: https://hexdocs.pm/fastdecimal/migration.html Include both fastdecimal and the original decimal library in your dependencies. ```elixir def deps do [ {:fastdecimal, "~> 1.0"}, {:decimal, "~> 2.1"} # keep — Ecto and other libs still pull it in ] end ``` -------------------------------- ### to_string(a, format) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Converts a decimal value to its string representation. ```APIDOC ## to_string(a, format) ### Description Converts the input decimal to a string, optionally using a specific format. ### Signature `to_string(input(), FastDecimal.to_string_format()) :: String.t()` ``` -------------------------------- ### Calculate quotient and remainder with div_rem/2 Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns a tuple containing the quotient and remainder, where the quotient is computed via integer division. ```elixir @spec div_rem(t(), t()) :: {t(), t()} ``` ```elixir iex> FastDecimal.div_rem(FastDecimal.new("10"), FastDecimal.new("3")) {%FastDecimal{coef: 3, exp: 0}, %FastDecimal{coef: 1, exp: 0}} ``` -------------------------------- ### Check for decimal v2.4 / v3.x specific API usage Source: https://hexdocs.pm/fastdecimal/migration.html Identify usage of :max_digits and :max_exponent options which must be removed during migration. ```bash grep -rn "Decimal\.\(parse\|cast\|new\)\(.*,.*max_\|Decimal\.to_string\(.*,.*max_" lib/ test/ ``` -------------------------------- ### Comparison & Predicates Source: https://hexdocs.pm/fastdecimal/readme.html Functions for comparing decimal values and checking their properties. ```APIDOC ## Comparison Methods - `FastDecimal.compare(a, b)`: Returns `:lt`, `:eq`, `:gt`, or `:nan`. - `FastDecimal.equal?(a, b)` - `FastDecimal.lt?(a, b)` - `FastDecimal.gt?(a, b)` - `FastDecimal.min(a, b)` - `FastDecimal.max(a, b)` ## Predicates - `FastDecimal.zero?(d)`, `FastDecimal.positive?(d)`, `FastDecimal.negative?(d)` - `FastDecimal.nan?(d)`, `FastDecimal.inf?(d)`, `FastDecimal.finite?(d)` ``` -------------------------------- ### Convert to string Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Converts a decimal-compatible input to its string representation, optionally using a specific format. ```elixir @spec to_string(input()) :: String.t() ``` ```elixir @spec to_string(input(), FastDecimal.to_string_format()) :: String.t() ``` -------------------------------- ### Create negative infinity Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Returns a negative infinity decimal value. ```elixir @spec neg_inf() :: FastDecimal.t() ``` -------------------------------- ### Batch operations Source: https://hexdocs.pm/fastdecimal/index.html Perform operations on lists of decimals efficiently. ```elixir FastDecimal.sum(list) # Tight Elixir-side reduce FastDecimal.product(list) ``` -------------------------------- ### to_string(decimal, format) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Formats a FastDecimal as a string using various supported formats. ```APIDOC ## to_string(decimal, format) ### Description Formats a decimal as a string. Supported formats include :normal, :scientific, :raw, and :xsd. ### Signature `to_string(t(), to_string_format()) :: String.t()` ### Parameters - **decimal** (t()) - The FastDecimal to format. - **format** (to_string_format()) - The formatting style to apply (defaults to :normal). ``` -------------------------------- ### Locate struct literals and context usage Source: https://hexdocs.pm/fastdecimal/migration.html Use grep to find occurrences of Decimal structs or context usage that require manual refactoring. ```bash grep -rn "%Decimal{" lib/ test/ ``` ```bash grep -rn "Decimal.Context" lib/ test/ ``` -------------------------------- ### add(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Adds two decimal values. ```APIDOC ## add(a, b) ### Signature `add(input(), input()) :: FastDecimal.t()` ``` -------------------------------- ### Define from_integer specification Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Specifies the from_integer function signature. ```elixir @spec from_integer(integer()) :: t() ``` -------------------------------- ### Sum a List of FastDecimals Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Sums a list of FastDecimals using an inlined, recursion-flat approach to avoid function call overhead. ```elixir @spec sum([t()]) :: t() ``` -------------------------------- ### Perform integer division with div_int/2 Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Truncates the fractional part toward zero, returning a result with an exponent of 0. ```elixir @spec div_int(t(), t()) :: t() ``` ```elixir iex> FastDecimal.div_int(FastDecimal.new("10.5"), FastDecimal.new("3")) %FastDecimal{coef: 3, exp: 0} ``` -------------------------------- ### Compare two decimals Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Compares two FastDecimal values and returns the relationship. ```elixir @spec compare(t(), t()) :: :lt | :eq | :gt | :nan ``` -------------------------------- ### Alias FastDecimal.Compat as Decimal Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Use this alias to route existing Decimal calls to the FastDecimal compatibility layer. ```elixir alias FastDecimal.Compat, as: Decimal ``` -------------------------------- ### add(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Adds two FastDecimal values together. ```APIDOC ## add(t(), t()) ### Description Adds two FastDecimal values together. ### Signature `add(t(), t()) :: t()` ``` -------------------------------- ### lt?(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Checks if the first decimal is less than the second. ```APIDOC ## lt?(a, b) ### Signature `@spec lt?(t(), t()) :: boolean()` ``` -------------------------------- ### FastDecimal.div/3 Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Performs division with configurable precision. ```APIDOC ## FastDecimal.div(a, b, opts \\ []) ### Description Divides two decimals. Unlike other operations, this requires a precision argument to handle non-terminating decimals. ### Parameters - **a** (t()) - Dividend - **b** (t()) - Divisor - **opts** (keyword) - Optional configuration, including `precision` ### Example ```elixir FastDecimal.div(FastDecimal.new("10"), FastDecimal.new("3"), precision: 5) ``` ``` -------------------------------- ### div(a, b, opts) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Performs division on two decimal values with optional precision and rounding settings. ```APIDOC ## div(a, b, opts \\ []) ### Signature `div(input(), input(), keyword()) :: FastDecimal.t()` ``` -------------------------------- ### sqrt(a, opts) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Calculates the square root of a decimal value. ```APIDOC ## sqrt(a, opts) ### Description Computes the square root of the input decimal with optional configuration. ### Signature `sqrt(input(), keyword()) :: FastDecimal.t()` ``` -------------------------------- ### Performing arithmetic operations Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Execute exact addition or division with specified precision. ```elixir iex> FastDecimal.add(FastDecimal.new("1.23"), FastDecimal.new("4.567")) %FastDecimal{coef: 5797, exp: -3} iex> FastDecimal.div(FastDecimal.new("10"), FastDecimal.new("3"), precision: 5) %FastDecimal{coef: 33333, exp: -4} ``` -------------------------------- ### from_integer(int) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Creates a FastDecimal from an integer. ```APIDOC ## from_integer(int) ### Signature `@spec from_integer(integer()) :: t()` ``` -------------------------------- ### Compare two values Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Compares two inputs and returns the relationship status. ```elixir @spec cmp(input(), input()) :: :lt | :eq | :gt | :nan ``` ```elixir @spec compare(input(), input()) :: :lt | :eq | :gt | :nan ``` -------------------------------- ### FastDecimal.new/1,2 Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Constructs a new FastDecimal struct from a string or integer/exponent pair. ```APIDOC ## FastDecimal.new(value) ### Description Creates a new FastDecimal instance. ### Signature - `new(string)` - `new(coef, exp)` ### Examples ```elixir FastDecimal.new("1.23") FastDecimal.new(123, -2) ``` ``` -------------------------------- ### inf() Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns the +∞ sentinel value. ```APIDOC ## inf() ### Signature `@spec inf() :: t()` ``` -------------------------------- ### Check for zero Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Determines if the provided input is equivalent to zero. ```elixir @spec zero?(input()) :: boolean() ``` -------------------------------- ### equal?(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Checks if two decimal values are equal. ```APIDOC ## equal?(a, b) ### Signature `equal?(input(), input()) :: boolean()` ``` -------------------------------- ### Calculate Square Root with FastDecimal Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Computes the square root using the Newton-Raphson method with configurable precision. ```elixir @spec sqrt( t(), keyword() ) :: t() ``` ```elixir iex> FastDecimal.sqrt(FastDecimal.new("4")) %FastDecimal{coef: 2, exp: 0} iex> FastDecimal.sqrt(FastDecimal.new("2"), precision: 10) %FastDecimal{coef: 1414213562, exp: -9} ``` -------------------------------- ### Handle precision context changes Source: https://hexdocs.pm/fastdecimal/migration.html Replace implicit context-based precision with explicit per-call precision or a custom wrapper module. ```elixir # Before (implicit context): def init(_) do Decimal.Context.set(%Decimal.Context{precision: 18, rounding: :half_even}) # ... downstream code calls Decimal.div(a, b) with implicit precision: 18 end # After (explicit per-call): @precision 18 @rounding :half_even defp my_div(a, b), do: FastDecimal.div(a, b, precision: @precision, rounding: @rounding) # ... use my_div instead of Decimal.div throughout ``` ```elixir defmodule MyApp.Decimal do @precision 18 @rounding :half_even def div(a, b), do: FastDecimal.div(a, b, precision: @precision, rounding: @rounding) def sqrt(a), do: FastDecimal.sqrt(a, precision: @precision) def round(a, places), do: FastDecimal.round(a, places, @rounding) # delegate the rest to FastDecimal — they don't take precision defdelegate add(a, b), to: FastDecimal defdelegate sub(a, b), to: FastDecimal defdelegate mult(a, b), to: FastDecimal defdelegate compare(a, b), to: FastDecimal # ... etc end ``` -------------------------------- ### Update is_decimal Import Source: https://hexdocs.pm/fastdecimal/migration.html Update the import statement for the is_decimal macro to use the FastDecimal implementation. ```elixir -import Decimal.Macros, only: [is_decimal: 1] +import FastDecimal, only: [is_decimal: 1] ``` -------------------------------- ### Convert to float Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Converts a decimal-compatible input to a standard float. ```elixir @spec to_float(input()) :: float() ``` -------------------------------- ### Compare decimals with equal?/2 Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Checks for equality between two decimals, noting that NaN values never compare as equal. ```elixir @spec equal?(t(), t()) :: boolean() ``` -------------------------------- ### FastDecimal Construction Source: https://hexdocs.pm/fastdecimal/readme.html Methods for creating FastDecimal types from various inputs including strings, integers, and scientific notation. ```APIDOC ## FastDecimal.new/1,2 ### Description Creates a new FastDecimal instance. `new/1` parses input and raises on error, while `new/2` constructs from coefficient and exponent. ## FastDecimal.parse/1 ### Description Parses a string into a FastDecimal instance, returning `{:ok, t}` or `:error` without raising. ## FastDecimal.cast/1 ### Description Performs a soft parse of various input types (Decimal, int, string, float, nil) into a FastDecimal. ``` -------------------------------- ### Return positive value Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Returns the positive version of the input. ```elixir @spec plus(input()) :: FastDecimal.t() ``` -------------------------------- ### to_float(a) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Converts a decimal value to a float. ```APIDOC ## to_float(a) ### Description Converts the input decimal to a floating-point number. ### Signature `to_float(input()) :: float()` ``` -------------------------------- ### Division with remainder Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Performs division and returns both the quotient and remainder. ```elixir @spec div_rem(input(), input()) :: {FastDecimal.t(), FastDecimal.t()} ``` -------------------------------- ### min(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns the smaller of two decimals. ```APIDOC ## min(a, b) ### Description The smaller of two decimals. If exactly one operand is NaN, the number is returned (IEEE 754 minNum semantics, matching Decimal.min/2); NaN is returned only when both operands are NaN. ### Signature `@spec min(t(), t()) :: t()` ``` -------------------------------- ### zero?(a) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Checks if a decimal value is zero. ```APIDOC ## zero?(a) ### Description Returns true if the input decimal is zero, otherwise false. ### Signature `zero?(input()) :: boolean()` ``` -------------------------------- ### Define min specification Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Specifies the minimum value function signature. ```elixir @spec min(t(), t()) :: t() ``` -------------------------------- ### FastDecimal.add/2 Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Performs exact addition of two FastDecimal values. ```APIDOC ## FastDecimal.add(a, b) ### Description Adds two FastDecimal structs. The operation is mathematically exact. ### Parameters - **a** (t()) - The first decimal - **b** (t()) - The second decimal ### Example ```elixir FastDecimal.add(FastDecimal.new("1.23"), FastDecimal.new("4.567")) ``` ``` -------------------------------- ### Parse a string to FastDecimal Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Attempts to parse a string into a FastDecimal, returning {:ok, t()} or :error. ```elixir @spec parse(String.t()) :: {:ok, t()} | :error ``` -------------------------------- ### parse(str) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Parses a string into a FastDecimal. ```APIDOC ## parse(String.t()) ### Description Parses a string into a FastDecimal. ### Signature `@spec parse(String.t()) :: {:ok, t()} | :error` ``` -------------------------------- ### neg_inf() Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns the -∞ sentinel value. ```APIDOC ## neg_inf() ### Signature `@spec neg_inf() :: t()` ``` -------------------------------- ### Convert to integer Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Converts a decimal-compatible input to an integer. ```elixir @spec to_integer(input()) :: integer() ``` -------------------------------- ### Check if finite Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Determines if the input is a finite number. ```elixir @spec finite?(input()) :: boolean() ``` -------------------------------- ### Check if infinite Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Determines if the input is infinite. ```elixir @spec inf?(input()) :: boolean() ``` -------------------------------- ### is_decimal(value) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Guard-safe predicate. True when the argument is a %FastDecimal{} struct. ```APIDOC ## is_decimal(value) ### Description Guard-safe predicate. True when the argument is a %FastDecimal{} struct. Mirrors Decimal.Macros.is_decimal/1 so it can be drop-in-substituted. ``` -------------------------------- ### Comparing decimal values Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Check for equality or compare values, noting that trailing zeros in the representation do not affect numerical equality. ```elixir iex> FastDecimal.compare(FastDecimal.new("1.10"), FastDecimal.new("1.1")) :eq iex> FastDecimal.equal?(FastDecimal.new("1.10"), FastDecimal.new("1.1")) true ``` -------------------------------- ### gt?(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Checks if the first decimal is greater than the second. ```APIDOC ## gt?(a, b) ### Signature `@spec gt?(t(), t()) :: boolean()` ``` -------------------------------- ### sum(list) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Calculates the sum of a list of FastDecimal values. ```APIDOC ## sum(list) ### Description Sums a list of FastDecimals. This implementation is optimized to be recursion-flat and avoids the overhead of anonymous function calls. ### Signature `sum([t()]) :: t()` ### Parameters - **list** ([t()]) - A list of FastDecimal structs to sum. ``` -------------------------------- ### nan() Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns the NaN sentinel value. ```APIDOC ## nan() ### Signature `@spec nan() :: t()` ``` -------------------------------- ### Calculate product of a list Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Computes the product of a list of FastDecimal values. ```elixir @spec product([t()]) :: t() ``` -------------------------------- ### Define input type Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Defines the accepted input types for FastDecimal functions. ```elixir @type input() :: FastDecimal.t() | Decimal.t() | integer() | binary() | float() | nil ``` -------------------------------- ### Add two decimals Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Performs addition on two FastDecimal values. ```elixir @spec add(t(), t()) :: t() ``` -------------------------------- ### FastDecimal.compare/2 Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Compares two FastDecimal values. ```APIDOC ## FastDecimal.compare(a, b) ### Description Compares two decimals and returns :eq, :lt, or :gt. ### Example ```elixir FastDecimal.compare(FastDecimal.new("1.10"), FastDecimal.new("1.1")) ``` ``` -------------------------------- ### Add two values Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Performs addition on two inputs. ```elixir @spec add(input(), input()) :: FastDecimal.t() ``` -------------------------------- ### Format FastDecimal as String Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Converts a FastDecimal to a string using specified formatting options like :normal, :scientific, :raw, or :xsd. ```elixir @spec to_string(t(), to_string_format()) :: String.t() ``` -------------------------------- ### Convert decimal values Source: https://hexdocs.pm/fastdecimal/index.html Convert decimals to strings, integers, or floats, and normalize representations. ```elixir FastDecimal.to_string(d) # "1.23" FastDecimal.to_string(d, :scientific) # "1.23" — IEEE compact (only emits E for very small/large) FastDecimal.to_string(d, :raw) # "123E-2" FastDecimal.to_string(d, :xsd) # XSD canonical (= :normal for our repr) FastDecimal.to_integer(d) # raises on fractional FastDecimal.to_float(d) # lossy for non-terminating binaries FastDecimal.normalize(d) # strips trailing zeros ``` -------------------------------- ### Check equality Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Checks if two inputs are equal. ```elixir @spec eq?(input(), input()) :: boolean() ``` ```elixir @spec equal?(input(), input()) :: boolean() ``` -------------------------------- ### to_integer(a) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Converts a decimal value to an integer. ```APIDOC ## to_integer(a) ### Description Converts the input decimal to an integer. ### Signature `to_integer(input()) :: integer()` ``` -------------------------------- ### Convert from float Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Converts a float to a FastDecimal. ```elixir @spec from_float(float()) :: FastDecimal.t() ``` -------------------------------- ### abs(a) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Calculates the absolute value of the input. ```APIDOC ## abs(a) ### Signature `abs(input()) :: FastDecimal.t()` ``` -------------------------------- ### Divide two values Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Performs division with optional precision and rounding settings. ```elixir @spec div(input(), input(), keyword()) :: FastDecimal.t() ``` -------------------------------- ### Define lt? specification Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Specifies the less-than comparison function signature. ```elixir @spec lt?(t(), t()) :: boolean() ``` -------------------------------- ### Perform arithmetic operations Source: https://hexdocs.pm/fastdecimal/index.html Execute standard arithmetic operations with configurable precision and rounding modes. ```elixir FastDecimal.add(a, b) FastDecimal.sub(a, b) FastDecimal.mult(a, b) FastDecimal.div(a, b, precision: 28, rounding: :half_even) # Exact quotients short-circuit (~30 ns) and # return Decimal's ideal-exponent form: div(10, 2) == ~d"5" FastDecimal.div_int(a, b) # Truncated integer division FastDecimal.div_rem(a, b) # {quotient, remainder} FastDecimal.rem(a, b) FastDecimal.negate(a) FastDecimal.abs(a) FastDecimal.sqrt(a, precision: 28) # Newton-Raphson FastDecimal.round(a, places, mode) # All 7 rounding modes ``` -------------------------------- ### Define neg_inf specification Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Specifies the negative infinity sentinel function signature. ```elixir @spec neg_inf() :: t() ``` -------------------------------- ### Define inf specification Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Specifies the infinity sentinel function signature. ```elixir @spec inf() :: t() ``` -------------------------------- ### Cast input value Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Attempts to cast an input to a FastDecimal type, returning :ok or :error. ```elixir @spec cast(input()) :: {:ok, FastDecimal.t()} | :error ``` -------------------------------- ### Integer division Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Performs integer division on two inputs. ```elixir @spec div_int(input(), input()) :: FastDecimal.t() ``` -------------------------------- ### Define nan specification Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Specifies the NaN sentinel function signature. ```elixir @spec nan() :: t() ``` -------------------------------- ### Infinity value Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Returns the infinity value. ```elixir @spec inf() :: FastDecimal.t() ``` -------------------------------- ### Check greater than Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Checks if the first input is greater than the second. ```elixir @spec gt?(input(), input()) :: boolean() ``` -------------------------------- ### div_int(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Performs integer (truncated) division on two FastDecimal values. ```APIDOC ## div_int(a, b) ### Description Performs integer (truncated) division. Like Kernel.div/2 for integers, it drops the fractional part, truncating toward zero. The result always has an exponent of 0. ### Signature `@spec div_int(t(), t()) :: t()` ### Example `FastDecimal.div_int(FastDecimal.new("10.5"), FastDecimal.new("3"))` ``` -------------------------------- ### inf?(fast_decimal) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns true if the value is +∞ or -∞. ```APIDOC ## inf?(fast_decimal) ### Signature `@spec inf?(t()) :: boolean()` ``` -------------------------------- ### Multiply two values (alias) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Alias for mult/2. ```elixir @spec multiply(input(), input()) :: FastDecimal.t() ``` -------------------------------- ### cast(value) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Attempts to cast the input value to a FastDecimal type. Returns {:ok, t} on success or :error. ```APIDOC ## cast(value) ### Signature `cast(input()) :: {:ok, FastDecimal.t()} | :error` ``` -------------------------------- ### Arithmetic Source: https://hexdocs.pm/fastdecimal/index.html Mathematical operations supported by the library. ```APIDOC ## Arithmetic Operations ### Description Standard arithmetic functions including add, sub, mult, div, div_int, div_rem, rem, negate, abs, sqrt, and round. ### Signatures - `FastDecimal.add(a, b)` - `FastDecimal.sub(a, b)` - `FastDecimal.mult(a, b)` - `FastDecimal.div(a, b, precision: 28, rounding: :half_even)` - `FastDecimal.div_int(a, b)` - `FastDecimal.div_rem(a, b)` - `FastDecimal.rem(a, b)` - `FastDecimal.negate(a)` - `FastDecimal.abs(a)` - `FastDecimal.sqrt(a, precision: 28)` - `FastDecimal.round(a, places, mode)` ``` -------------------------------- ### Cast input to FastDecimal Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Attempts to coerce various input types into a FastDecimal struct without raising errors. ```elixir @spec cast(t() | integer() | binary() | Decimal.t() | float() | nil) :: {:ok, t()} | :error ``` -------------------------------- ### zero?(fast_decimal) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Checks if a FastDecimal value is zero. ```APIDOC ## zero?(fast_decimal) ### Description Checks if the provided FastDecimal value is equal to zero. ### Signature `zero?(t()) :: boolean()` ### Parameters - **fast_decimal** (t()) - Required - The FastDecimal value to check. ### Returns - **boolean** - Returns true if the value is zero, otherwise false. ``` -------------------------------- ### Calculate square root Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Computes the square root of a decimal value with optional configuration. ```elixir @spec sqrt( input(), keyword() ) :: FastDecimal.t() ``` -------------------------------- ### sigil_d(arg, modifiers) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Compile-time literal sigil for creating FastDecimal values. ```APIDOC ## sigil_d(arg, modifiers) ### Description Compile-time literal sigil. `~d"1.23"` becomes a `%FastDecimal{}` at compile time, paying zero parse cost at runtime. ``` -------------------------------- ### Calculate negation Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Returns the negated value of the input. ```elixir @spec minus(input()) :: FastDecimal.t() ``` -------------------------------- ### Normalize a FastDecimal Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Strips trailing zeros from the coefficient and adjusts the exponent accordingly. ```elixir @spec normalize(t()) :: t() ``` -------------------------------- ### div_rem(arg1, arg2) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns the quotient and remainder of a division operation. ```APIDOC ## div_rem(arg1, arg2) ### Description Returns a tuple {quotient, remainder} such that a == quotient * b + remainder. The quotient is computed using div_int/2. ### Signature `@spec div_rem(t(), t()) :: {t(), t()}` ### Example `FastDecimal.div_rem(FastDecimal.new("10"), FastDecimal.new("3"))` ``` -------------------------------- ### Find minimum of two values Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Returns the smaller of two decimal values. ```elixir @spec min(input(), input()) :: FastDecimal.t() ``` -------------------------------- ### Normalize decimal Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Normalizes the decimal representation. ```elixir @spec normalize(input()) :: FastDecimal.t() ``` -------------------------------- ### Define inf? specification Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Specifies the infinity check function signature. ```elixir @spec inf?(t()) :: boolean() ``` -------------------------------- ### finite?(fast_decimal) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Checks if a FastDecimal value is finite. ```APIDOC ## finite?(fast_decimal) ### Description Returns true if the value is a finite number (not NaN, not infinity). ### Signature `@spec finite?(t()) :: boolean()` ``` -------------------------------- ### mult(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Multiplies two decimals. ```APIDOC ## mult(a, b) ### Signature `@spec mult(t(), t()) :: t()` ``` -------------------------------- ### Define nan? specification Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Specifies the NaN check function signature. ```elixir @spec nan?(t()) :: boolean() ``` -------------------------------- ### Define gt? specification Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Specifies the greater-than comparison function signature. ```elixir @spec gt?(t(), t()) :: boolean() ``` -------------------------------- ### Reduce decimal Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Reduces the decimal representation. ```elixir @spec reduce(input()) :: FastDecimal.t() ``` -------------------------------- ### Check if negative Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns true if the decimal is negative. ```elixir @spec negative?(t()) :: boolean() ``` -------------------------------- ### Check if value is negative Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Determines if the input is less than zero. ```elixir @spec negative?(input()) :: boolean() ``` -------------------------------- ### Check for finite values with finite?/1 Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns true if the provided decimal is a finite number, excluding NaN and infinity. ```elixir @spec finite?(t()) :: boolean() ``` -------------------------------- ### Check if positive Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns true if the decimal is positive. ```elixir @spec positive?(t()) :: boolean() ``` -------------------------------- ### normalize(d) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Strips trailing zeros from the coefficient, raising the exponent. ```APIDOC ## normalize(t()) ### Description Strip trailing zeros from the coefficient, raising the exponent. `~d"1.10"` (coef=110, exp=-2) becomes `~d"1.1"` (coef=11, exp=-1). ### Signature `@spec normalize(t()) :: t()` ``` -------------------------------- ### Multiply two values Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Multiplies two decimal inputs. ```elixir @spec mult(input(), input()) :: FastDecimal.t() ``` -------------------------------- ### Calculate absolute value Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Returns the absolute value of the input. ```elixir @spec abs(input()) :: FastDecimal.t() ``` -------------------------------- ### max(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Returns the larger of two decimals. ```APIDOC ## max(a, b) ### Description The larger of two decimals. If exactly one operand is NaN, the number is returned (IEEE 754 maxNum semantics, matching Decimal.max/2); NaN is returned only when both operands are NaN. ### Signature `@spec max(t(), t()) :: t()` ``` -------------------------------- ### round(a, places, mode) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Rounds a decimal value to a specified number of decimal places using a defined rounding mode. ```APIDOC ## round(a, places, mode) ### Description Rounds the input decimal to the specified number of places using the provided rounding mode. ### Signature `round(input(), integer(), FastDecimal.rounding_mode()) :: FastDecimal.t()` ``` -------------------------------- ### negative?(fast_decimal) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Checks if the given FastDecimal is negative. ```APIDOC ## negative?(t()) ### Description Checks if the given FastDecimal is negative. ### Signature `@spec negative?(t()) :: boolean()` ``` -------------------------------- ### Define mult specification Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Specifies the multiplication function signature. ```elixir @spec mult(t(), t()) :: t() ``` -------------------------------- ### Create NaN value Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Returns a Not-a-Number decimal value. ```elixir @spec nan() :: FastDecimal.t() ``` -------------------------------- ### sub(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.Compat.html Subtracts one decimal value from another. ```APIDOC ## sub(a, b) ### Description Subtracts the second decimal value from the first. ### Signature `sub(input(), input()) :: FastDecimal.t()` ``` -------------------------------- ### rem(a, b) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Calculates the remainder of decimal division. ```APIDOC ## rem(t(), t()) ### Description Remainder of decimal division (same sign as the dividend). ### Signature `@spec rem(t(), t()) :: t()` ``` -------------------------------- ### positive?(fast_decimal) Source: https://hexdocs.pm/fastdecimal/FastDecimal.html Checks if the given FastDecimal is positive. ```APIDOC ## positive?(t()) ### Description Checks if the given FastDecimal is positive. ### Signature `@spec positive?(t()) :: boolean()` ``` -------------------------------- ### Define an Ecto schema with FastDecimal Source: https://hexdocs.pm/fastdecimal/FastDecimal.Ecto.Type.html Use FastDecimal.Ecto.Type as the field type within an Ecto schema to map database numeric columns to FastDecimal structs. ```elixir defmodule MyApp.Invoice do use Ecto.Schema schema "invoices" do field :total, FastDecimal.Ecto.Type end end ```