Home

Awesome

money

githubb codecovb goreportb godocb licenseb versionb awesomeb

Package money implements immutable monetary amounts and exchange rates for Go.

Features

Getting started

Installation

To add the money package to your Go workspace:

go get github.com/govalues/money

Usage

Create amount using one of the constructors. After creating a monetary amount, various operations can be performed:

package main

import (
    "fmt"
    "github.com/govalues/decimal"
    "github.com/govalues/money"
)

func main() {
    // Constructors
    a, _ := money.NewAmount("USD", 8, 0)               // a = USD 8.00
    b, _ := money.ParseAmount("USD", "12.5")           // b = USD 12.50
    c, _ := money.NewAmountFromFloat64("USD", 2.567)   // c = USD 2.567
    d, _ := money.NewAmountFromInt64("USD", 7, 896, 3) // d = USD 7.896
    r, _ := money.NewExchRate("USD", "EUR", 9, 1)      // r = USD/EUR 0.9
    x, _ := decimal.New(2, 0)                          // x = 2

    // Operations
    fmt.Println(a.Add(b))          // USD 8.00 + USD 12.50
    fmt.Println(a.Sub(b))          // USD 8.00 - USD 12.50

    fmt.Println(a.Mul(x))          // USD 8.00 * 2
    fmt.Println(a.FMA(x, b))       // USD 8.00 * 2 + USD 12.50
    fmt.Println(r.Conv(a))         // USD 8.00 * USD/EUR 0.9

    fmt.Println(a.Quo(x))          // USD 8.00 / 2
    fmt.Println(a.QuoRem(x))       // USD 8.00 div 2, USD 8.00 mod 2
    fmt.Println(a.Rat(b))          // USD 8.00 / USD 12.50
    fmt.Println(a.Split(3))        // USD 8.00 into 3 parts

    // Rounding to 2 decimal places
    fmt.Println(c.RoundToCurr())   // 2.57
    fmt.Println(c.CeilToCurr())    // 2.57
    fmt.Println(c.FloorToCurr())   // 2.56
    fmt.Println(c.TruncToCurr())   // 2.56

    // Conversions
    fmt.Println(d.Int64(9))        // 7 896000000
    fmt.Println(d.Float64())       // 7.896
    fmt.Println(d.String())        // USD 7.896

    // Formatting
    fmt.Printf("%v\n", d)          // USD 7.896
    fmt.Printf("%[1]f %[1]c\n", d) // 7.896 USD
    fmt.Printf("%f\n", d)          // 7.896
    fmt.Printf("%c\n", d)          // USD
    fmt.Printf("%d\n", d)          // 790
}

Documentation

For detailed documentation and additional examples, visit the package documentation.

Comparison

Comparison with other popular packages:

Featuregovaluesrhymond v1.0.10bojanz v1.2.1
SpeedHighMediumMedium
Numeric RepresentationFloating PointFixed PointFloating Point
Precision19 digits18 digits39 digits
Default RoundingHalf to evenNot supportedHalf up
Overflow ControlYesNo1Yes
Support for DivisionYesNoYes
Support for Currency ConversionYesNoYes

Benchmarks

goos: linux
goarch: amd64
pkg: github.com/govalues/money-tests
cpu: AMD Ryzen 7 3700C  with Radeon Vega Mobile Gfx 
Test CaseExpressiongovaluesrhymond v1.0.10bojanz v1.2.1govalues vs rhymondgovalues vs bojanz
AddUSD 2.00 + USD 3.0022.95n218.30n144.10n+851.41%+528.02%
MulUSD 2.00 * 321.80n133.40n239.60n+511.79%+998.83%
QuoFiniteUSD 2.00 / 480.12nn/a2468.05nn/a+484.19%
QuoInfiniteUSD 2.00 / 3602.1nn/a2512.4nn/a-14.91%
SplitUSD 2.00 into 10 parts374.9n897.0nn/a3+139.28%n/a
ConvUSD 2.00 * USD/EUR 0.830.88nn/a4348.50nn/a+1028.38%
ParseUSD 144.99n139.50n99.09n+210.07%+120.26%
ParseUSD 123.45661.45n148.60n240.90n+141.82%+292.03%
ParseUSD 123456789.1234567890131.2n204.4n253.0n+55.85%+92.87%
StringUSD 138.48n200.70n89.92n+421.50%+133.65%
StringUSD 123.45656.34n229.90n127.05n+308.02%+125.49%
StringUSD 123456789.123456789084.73n383.30n277.55n+352.38%+227.57%
Telcosee specification224.2nn/a51944.0nn/a+766.89%

The benchmark results shown in the table are provided for informational purposes only and may vary depending on your specific use case.

Contributing

Interested in contributing? Here's how to get started:

  1. Fork and clone the repository.
  2. Implement your changes.
  3. Write tests to cover your changes.
  4. Ensure all tests pass with go test.
  5. Commit and push to your fork.
  6. Open a pull request detailing your changes.

Note: If you're considering significant changes, please open an issue first to discuss with the maintainers. This ensures alignment with the project's objectives and roadmap.

Footnotes

  1. rhymond does not detect overflow and returns an invalid result. For example, 92,233,720,368,547,758.07 + 0.01 results in -92,233,720,368,547,758.08.

  2. rhymond does not support division. 2

  3. bojanz does not support splitting into parts.

  4. rhymond does not support currency conversion.

  5. rhymond does not support multiplication by a fraction.