ProductPromotion
Logo

Go.Lang

made by https://0x3d.site

GitHub - nikolaydubina/fpmoney: 🧧 Fixed-Point Decimal Money
🧧 Fixed-Point Decimal Money. Contribute to nikolaydubina/fpmoney development by creating an account on GitHub.
Visit Site

GitHub - nikolaydubina/fpmoney: 🧧 Fixed-Point Decimal Money

GitHub - nikolaydubina/fpmoney: 🧧 Fixed-Point Decimal Money

🧧 Fixed-Point Decimal Money

codecov Go Report Card Go Reference Mentioned in Awesome Go OpenSSF Scorecard

Be Precise: using floats to represent currency is almost criminal. — Robert.C.Martin, "Clean Code" p.301

  • as fast as int64
  • no float in parsing nor printing, does not leak precision
  • ISO 4217 currency
  • block mismatched currency arithmetics
  • 100 LOC
  • fuzz tests
var BuySP500Price = fpmoney.FromInt(9000, fpmoney.SGD)

input := []byte(`{"sp500": {"amount": 9000.02, "currency": "SGD"}}`)

type Stonks struct {
    SP500 fpmoney.Amount `json:"sp500"`
}
var v Stonks
if err := json.Unmarshal(input, &v); err != nil {
    log.Fatal(err)
}

amountToBuy := fpmoney.FromInt(0, fpmoney.SGD)
if v.SP500.GreaterThan(BuySP500Price) {
    amountToBuy = amountToBuy.Add(v.SP500.Mul(2))
}

fmt.Println(amountToBuy)
// Output: 18000.04 SGD

Ultra Small Fractions

Some denominations have very low fractions. Storing them int64 you would get.

  • BTC satoshi is 1 BTC = 100,000,000 satoshi, which is still enough for ~92,233,720,368 BTC.
  • ETH wei is 1 ETH = 1,000,000,000,000,000,000 wei, which is ~9 ETH. If you deal with wei, you may consider bigint or multiple int64. In fact, official Ethereum code is in Go and it is using bigint (code).

Benchmarks

$ go test -bench=. -benchmem . > fpmoney.bench
$ go test -bench=. -benchmem ./internal/bench/float32 > float32.bench
$ go test -bench=. -benchmem ./internal/bench/int > int.bench
$ benchstat -split="XYZ" int.bench float32.bench fpmoney.bench
name \ time/op              int.bench   float32.bench  fpmoney.bench
JSONUnmarshal/small-16      383ns ± 0%     408ns ± 0%     294ns ± 0%
JSONUnmarshal/large-16      436ns ± 0%     473ns ± 0%     365ns ± 0%
JSONMarshal/small-16        115ns ± 0%     158ns ± 0%     226ns ± 0%
JSONMarshal/large-16        112ns ± 0%     146ns ± 0%     272ns ± 0%

name \ alloc/op             int.bench   float32.bench  fpmoney.bench
JSONUnmarshal/small-16       268B ± 0%      270B ± 0%      198B ± 0%
JSONUnmarshal/large-16       272B ± 0%      288B ± 0%      216B ± 0%
JSONMarshal/small-16        57.0B ± 0%     66.0B ± 0%    160.0B ± 0%
JSONMarshal/large-16        72.0B ± 0%     72.0B ± 0%    176.0B ± 0%

name \ allocs/op            int.bench   float32.bench  fpmoney.bench
JSONUnmarshal/small-16       6.00 ± 0%      6.00 ± 0%      3.00 ± 0%
JSONUnmarshal/large-16       6.00 ± 0%      6.00 ± 0%      3.00 ± 0%
JSONMarshal/small-16         2.00 ± 0%      2.00 ± 0%      3.00 ± 0%
JSONMarshal/large-16         2.00 ± 0%      2.00 ± 0%      3.00 ± 0%
goos: darwin
goarch: arm64
pkg: github.com/nikolaydubina/fpmoney
BenchmarkArithmetic/add_x1-16         1000000000	         0.54 ns/op	       0 B/op	       0 allocs/op
BenchmarkArithmetic/add_x100-16       	26382420	        44.42 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/nikolaydubina/fpmoney	14.200s

References and Related Work

  • ferdypruis/iso4217 was a good inspiration and reference material. it was used in early version as well. it is well maintained and fast library for currencies.
  • github.com/shopspring/decimal: fixed precision; faster printing/parsing/arithmetics; currency handling
  • github.com/Rhymond/go-money: does not use float or interface{} in parsing; currency is enum
  • github.com/ferdypruis/iso4217: skipped deprecated currencies to fit into uint8 and smaller struct size

Articles
to learn more about the golang concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here 🔥.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here 🔥.

Queries
or most google FAQ's about GoLang.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory