Bourse.Precise (bourse v0.1.0)

Copy Markdown View Source

Money-exact decimal string arithmetic for response normalization.

The contract is string in, string out: operands and results are decimal strings, never floats. A computed field such as trade cost = amount × price therefore remains "10.4727" for "0.0001" × "104727.0" instead of acquiring binary-float drift.

Only the operations the response-normalization layer needs (add, mul, div) are ported.

Semantics

  • A nil operand returns nil.
  • string_div/3 truncates toward zero to precision decimal places using Decimal :down rounding. Default precision is 18; precision may be zero or negative.
  • Division by zero returns nil.
  • Results are reduced (trailing zeros trimmed) and never scientific notation.

Summary

Functions

Adds two decimal strings, returning a reduced decimal string (or nil).

Divides two decimal strings, truncating toward zero to precision decimal places. Returns a reduced decimal string, or nil on a nil operand or a zero divisor.

Multiplies two decimal strings, returning a reduced decimal string (or nil).

Functions

string_add(string1, string2)

@spec string_add(String.t() | nil, String.t() | nil) :: String.t() | nil

Adds two decimal strings, returning a reduced decimal string (or nil).

string_div(string1, string2, precision \\ 18)

@spec string_div(String.t() | nil, String.t() | nil, integer()) :: String.t() | nil

Divides two decimal strings, truncating toward zero to precision decimal places. Returns a reduced decimal string, or nil on a nil operand or a zero divisor.

iex> Bourse.Precise.string_div("69696900000", "1e8")
"696.969"
iex> Bourse.Precise.string_div("0.00000002", "69696900000", 19)
"0.0000000000000000002"
iex> Bourse.Precise.string_div("5", "0")
nil

string_mul(string1, string2)

@spec string_mul(String.t() | nil, String.t() | nil) :: String.t() | nil

Multiplies two decimal strings, returning a reduced decimal string (or nil).

iex> Bourse.Precise.string_mul("0.0001", "104727.0")
"10.4727"
iex> Bourse.Precise.string_mul("0.00000002", "69696900000")
"1393.938"
iex> Bourse.Precise.string_mul(nil, "5")
nil