money

package
v1.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package money provides a small, allocation-free value type for representing monetary amounts as an integer number of minor units ("cents") plus a currency, together with overflow-checked arithmetic and locale-neutral formatting.

Why a type instead of a bare int64

Backend pricing that passes raw int64 cents around is a bug farm: it is easy to add two amounts in different currencies, to lose pennies when splitting a charge, or to silently overflow an int64 on a large multiply. Money makes those mistakes either impossible or loud:

  • Currency is carried with the amount, so Add/Sub/Cmp refuse to combine mismatched currencies (ErrCurrencyMismatch) instead of producing a nonsense number.
  • Arithmetic is overflow-checked and returns ErrOverflow rather than wrapping around.
  • Allocate splits an amount across ratios WITHOUT losing or inventing minor units — the classic "split the bill" problem.

Representation

A Money holds an int64 count of the currency's smallest unit and the ISO 4217 currency code. For USD/EUR/GBP that unit is the cent (2 decimal digits); for JPY it is the yen itself (0 decimal digits). The stored count is called "cents" throughout because that is the common case and the name the frontend's formatMoneyCents helper uses — but Format renders using the currency's actual decimal digits, so JPY formats without a fractional part.

The zero Money{} is a valid amount of zero in the empty currency (""). Two zero-currency amounts combine fine; combining "" with "USD" is a mismatch.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrCurrencyMismatch is returned when an operation combines two amounts
	// whose currencies differ.
	ErrCurrencyMismatch = errors.New("money: currency mismatch")
	// ErrOverflow is returned when a result does not fit in int64.
	ErrOverflow = errors.New("money: int64 overflow")
	// ErrDivideByZero is returned by Allocate/MulRatio for a zero denominator.
	ErrDivideByZero = errors.New("money: division by zero")
	// ErrParse is returned when a decimal string cannot be parsed.
	ErrParse = errors.New("money: invalid decimal string")
)

Sentinel errors returned by the arithmetic and parsing helpers. Callers can match them with errors.Is.

Functions

This section is empty.

Types

type Currency

type Currency string

Currency is an ISO 4217 alphabetic currency code (e.g. "USD"). It is a bare string so callers may name currencies the registry does not know about; unknown currencies format with a code prefix and default to 2 decimal digits.

const (
	USD Currency = "USD"
	EUR Currency = "EUR"
	GBP Currency = "GBP"
	JPY Currency = "JPY"
	CAD Currency = "CAD"
	AUD Currency = "AUD"
	CHF Currency = "CHF"
	CNY Currency = "CNY"
	INR Currency = "INR"
	BRL Currency = "BRL"
)

Common currencies. This is not an exhaustive ISO 4217 list — it is the set with registered display metadata (symbol + decimal digits). Any other code still works as a Currency value.

type Money

type Money struct {
	// contains filtered or unexported fields
}

Money is a monetary amount: an int64 count of the currency's minor unit plus the currency itself. The zero value is a valid zero amount in currency "".

func FromCents

func FromCents(cents int64, currency Currency) Money

FromCents constructs a Money from a raw minor-unit count and currency. This is the primary constructor and the direct counterpart to the frontend's formatMoneyCents(cents, currency): both take the same integer minor-unit amount.

func FromMajor

func FromMajor(major int64, currency Currency) (Money, error)

FromMajor constructs a Money from a whole-unit amount (e.g. FromMajor(12, USD) == $12.00). It returns ErrOverflow if the scaled value does not fit in int64.

func Parse

func Parse(s string, currency Currency) (Money, error)

Parse reads a decimal string like "12.34", "-1,234.56", or "1000" into a Money of the given currency, using that currency's decimal digits. Thousands separators (commas) and surrounding whitespace are tolerated; more fractional digits than the currency allows, or any non-numeric junk, is an ErrParse.

func Zero

func Zero(currency Currency) Money

Zero returns the zero amount in the given currency.

func (Money) Abs

func (m Money) Abs() Money

Abs returns the absolute value. math.MinInt64 is returned unchanged (it has no positive representation in int64).

func (Money) Add

func (m Money) Add(o Money) (Money, error)

Add returns m+o, or ErrCurrencyMismatch / ErrOverflow.

func (Money) Allocate

func (m Money) Allocate(ratios []int64) ([]Money, error)

Allocate splits the amount across len(ratios) parts in proportion to the given ratios, distributing every last minor unit so the parts sum EXACTLY back to the original (no pennies lost or invented). Remainder units left by integer division are handed out one at a time to the earliest parts, which makes the split deterministic and largest-remainder-fair enough for billing.

Ratios must be non-negative and not all zero; a negative ratio or an all-zero set returns an error. The sign of the amount is preserved.

func (Money) Cents

func (m Money) Cents() int64

Cents returns the raw minor-unit count. It is the value to hand to the frontend formatMoneyCents helper or to persist.

func (Money) Cmp

func (m Money) Cmp(o Money) (int, error)

Cmp compares two amounts of the same currency, returning -1, 0, or +1. It returns ErrCurrencyMismatch if the currencies differ.

func (Money) Currency

func (m Money) Currency() Currency

Currency returns the amount's currency.

func (Money) Equal

func (m Money) Equal(o Money) bool

Equal reports whether the two amounts have the same currency AND value. It never errors: mismatched currencies are simply not equal.

func (Money) Float64

func (m Money) Float64() float64

Float64 returns the amount as a float64 in major units (e.g. 12.34 for $12.34). It is a lossy convenience for display or coarse math only — never round-trip money through float64.

func (Money) Format

func (m Money) Format() string

Format renders the amount for display using the currency's symbol (or code) and decimal digits, with comma thousands-grouping on the integer part: FromCents(123456, USD).Format() == "$1,234.56"; a negative amount is "-$1,234.56"; JPY (0 digits) renders "¥1,234". Unknown currencies use a code prefix: FromCents(500, "XyZ").Format() == "XYZ 5.00".

func (Money) IsNegative

func (m Money) IsNegative() bool

IsNegative reports whether the amount is below zero.

func (Money) IsZero

func (m Money) IsZero() bool

IsZero reports whether the amount is exactly zero (currency-independent).

func (Money) Mul

func (m Money) Mul(factor int64) (Money, error)

Mul multiplies the amount by an integer factor (e.g. quantity), overflow- checked. The currency is preserved.

func (Money) MulRatio

func (m Money) MulRatio(num, den int64) (Money, error)

MulRatio scales the amount by the rational num/den, rounding the result to the nearest minor unit (ties rounded away from zero — the common financial rounding). It is the building block for percentages, tax, and discounts: a 7.5% tax is MulRatio(75, 1000); an 8th of a charge is MulRatio(1, 8).

The intermediate product is computed in arbitrary precision, so it never overflows mid-calculation; ErrOverflow is only returned if the ROUNDED result does not fit in int64. A zero denominator yields ErrDivideByZero.

func (Money) Neg

func (m Money) Neg() Money

Neg returns -m. math.MinInt64 has no positive counterpart, so it is clamped to itself; use Sub from Zero if you must detect that edge.

func (Money) String

func (m Money) String() string

String implements fmt.Stringer, returning the same rendering as Format.

func (Money) Sub

func (m Money) Sub(o Money) (Money, error)

Sub returns m-o, or ErrCurrencyMismatch / ErrOverflow.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL