fpmoney

🧧 Fixed-Point Decimal Money

https://github.com/nikolaydubina/fpmoney

Science Score: 44.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • βœ“
    CITATION.cff file
    Found CITATION.cff file
  • βœ“
    codemeta.json file
    Found codemeta.json file
  • βœ“
    .zenodo.json file
    Found .zenodo.json file
  • β—‹
    DOI references
  • β—‹
    Academic publication links
  • β—‹
    Committers with academic emails
  • β—‹
    Institutional organization owner
  • β—‹
    JOSS paper metadata
  • β—‹
    Scientific vocabulary similarity
    Low similarity (6.9%) to scientific vocabulary

Keywords

benchmarks decimal decimals encoding fixed-point go golang money vocabulary

Keywords from Contributors

generic interactive mesh interpretability profiles sequences projection standardization optim embedded
Last synced: 6 months ago · JSON representation ·

Repository

🧧 Fixed-Point Decimal Money

Basic Info
  • Host: GitHub
  • Owner: nikolaydubina
  • License: mit
  • Language: Go
  • Default Branch: master
  • Homepage:
  • Size: 901 KB
Statistics
  • Stars: 34
  • Watchers: 2
  • Forks: 1
  • Open Issues: 3
  • Releases: 29
Topics
benchmarks decimal decimals encoding fixed-point go golang money vocabulary
Created over 3 years ago · Last pushed 7 months ago
Metadata Files
Readme License Citation Codeowners Security

README.md

🧧 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[^1][^2] currency
  • block mismatched currency arithmetics
  • 100 LOC
  • fuzz tests

```go 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

bash $ go test -bench=. -benchmem . goos: darwin goarch: arm64 pkg: github.com/nikolaydubina/fpmoney cpu: Apple M3 Max BenchmarkCurrency_UnmarshalText-16 711695404 1.610 ns/op 0 B/op 0 allocs/op BenchmarkCurrency_AppendText-16 446232057 2.698 ns/op 0 B/op 0 allocs/op BenchmarkCurrency_MarshalText-16 81956246 13.99 ns/op 8 B/op 1 allocs/op BenchmarkCurrency_String-16 1000000000 1.064 ns/op 0 B/op 0 allocs/op BenchmarkArithmetic/add-16 924924993 1.305 ns/op 0 B/op 0 allocs/op BenchmarkJSON/small/encode-16 6004620 198.5 ns/op 160 B/op 3 allocs/op BenchmarkJSON/small/decode-16 5047149 238.7 ns/op 152 B/op 2 allocs/op BenchmarkJSON/large/encode-16 4739722 255.7 ns/op 176 B/op 3 allocs/op BenchmarkJSON/large/decode-16 3737406 315.3 ns/op 152 B/op 2 allocs/op BenchmarkBinary/small/encode-16 132380481 9.044 ns/op 16 B/op 1 allocs/op BenchmarkBinary/small/decode-16 100000000 10.80 ns/op 16 B/op 1 allocs/op BenchmarkBinary/large/encode-16 133549021 8.995 ns/op 16 B/op 1 allocs/op BenchmarkBinary/large/decode-16 100000000 10.61 ns/op 16 B/op 1 allocs/op PASS ok github.com/nikolaydubina/fpmoney 15.804s

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
  • https://en.wikipedia.org/wiki/ISO_4217

[^1]: excluding currencies with 4+ minor units CLF, UYW [^2]: excluding deprecated currencies HRD, HRK, SLL, ZWL

Owner

  • Name: Nikolay Dubina
  • Login: nikolaydubina
  • Kind: user

Citation (CITATION.cff)

cff-version: 1.2.0
message: If you reference this library in publication, please cite it as below.
title: Fixed Point currency aware money type in Go
abstract: High-performance, currency-aware fixed point money type in Go
authors:
- family-names: Dubina
  given-names: Nikolay
version: 2.1
date-released: 2022-06-21
license: MIT
repository-code: https://github.com/nikolaydubina/fpmoney
url: https://github.com/nikolaydubina/fpmoney

GitHub Events

Total
  • Release event: 6
  • Watch event: 4
  • Delete event: 2
  • Issue comment event: 1
  • Push event: 13
  • Pull request event: 5
  • Create event: 10
Last Year
  • Release event: 6
  • Watch event: 4
  • Delete event: 2
  • Issue comment event: 1
  • Push event: 13
  • Pull request event: 5
  • Create event: 10

Committers

Last synced: over 1 year ago

All Time
  • Total Commits: 75
  • Total Committers: 3
  • Avg Commits per committer: 25.0
  • Development Distribution Score (DDS): 0.04
Past Year
  • Commits: 16
  • Committers: 3
  • Avg Commits per committer: 5.333
  • Development Distribution Score (DDS): 0.188
Top Committers
Name Email Commits
Nikolay Dubina n****b@g****m 72
dependabot[bot] 4****] 2
Michael WΓΌrtinger m****l@w****e 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 10 months ago

All Time
  • Total issues: 2
  • Total pull requests: 11
  • Average time to close issues: N/A
  • Average time to close pull requests: about 3 hours
  • Total issue authors: 1
  • Total pull request authors: 3
  • Average comments per issue: 1.0
  • Average comments per pull request: 0.45
  • Merged pull requests: 10
  • Bot issues: 0
  • Bot pull requests: 2
Past Year
  • Issues: 0
  • Pull requests: 4
  • Average time to close issues: N/A
  • Average time to close pull requests: about 8 hours
  • Issue authors: 0
  • Pull request authors: 2
  • Average comments per issue: 0
  • Average comments per pull request: 0.5
  • Merged pull requests: 3
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • totemcaf (2)
  • nikolaydubina (1)
Pull Request Authors
  • nikolaydubina (13)
  • dependabot[bot] (4)
  • mwuertinger (2)
Top Labels
Issue Labels
enhancement (2)
Pull Request Labels
dependencies (4)

Dependencies

go.mod go
  • github.com/ferdypruis/iso4217 v1.2.1
  • github.com/nikolaydubina/fpdecimal v0.10.1
  • golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d
go.sum go
  • github.com/ferdypruis/iso4217 v1.2.0
  • github.com/ferdypruis/iso4217 v1.2.1
  • github.com/nikolaydubina/fpdecimal v0.10.0
  • github.com/nikolaydubina/fpdecimal v0.10.1
  • golang.org/x/exp v0.0.0-20220609121020-a51bd0440498
  • golang.org/x/exp v0.0.0-20220613132600-b0d781184e0d
.github/workflows/tests.yml actions
  • actions/checkout v2 composite
  • actions/setup-go v2 composite
  • codecov/codecov-action v2 composite
.github/workflows/scorecard.yml actions
  • actions/checkout v3.1.0 composite
  • actions/upload-artifact v3.1.0 composite
  • github/codeql-action/upload-sarif v2.2.4 composite
  • ossf/scorecard-action v2.3.1 composite