https://github.com/naughtygopher/currency
A currency computations package.
https://github.com/naughtygopher/currency
List: currency
awesome-go awesome-golang awesome-list currency currency-api currency-computations currency-format finance go-library go-package golang-module golang-package
Last synced: 24 days ago
JSON representation
A currency computations package.
- Host: GitHub
- URL: https://github.com/naughtygopher/currency
- Owner: naughtygopher
- License: mit
- Created: 2017-05-09T06:06:38.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2024-10-12T10:20:13.000Z (7 months ago)
- Last Synced: 2025-04-09T17:01:33.262Z (24 days ago)
- Topics: awesome-go, awesome-golang, awesome-list, currency, currency-api, currency-computations, currency-format, finance, go-library, go-package, golang-module, golang-package
- Language: Go
- Homepage:
- Size: 64.5 KB
- Stars: 61
- Watchers: 6
- Forks: 9
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-go - currency - High performant & accurate currency computation package. (Financial / Search and Analytic Databases)
- awesome-go-extra - currency - 05-09T06:06:38Z|2021-11-13T17:10:30Z| (Financial / Advanced Console UIs)
README
[](https://github.com/naughtygopher/currency/actions)
[](https://pkg.go.dev/github.com/naughtygopher/currency)
[](https://goreportcard.com/report/github.com/naughtygopher/currency)
[](https://coveralls.io/github/naughtygopher/currency?branch=master)
[](https://github.com/avelino/awesome-go/tree/main?tab=readme-ov-file#financial)
[](https://github.com/creativecreature/sturdyc/blob/master/LICENSE)## Currency v2.0.1
Currency package helps you do currency computations accurately. `Currency` struct holds all the data required to define a currency.
```golang
type Currency struct {
// Code represents the international currency code
Code string
// Symbol is the respective currency symbol
Symbol string
// Main represents the main value of the currency
Main int
// Fractional represents the fractional/sub unit of the currency
Fractional uint
// FUName is the name of the fractional/sub unit of the currency. e.g. paise
FUName string
// FUShare represents the no.of fractional/sub units that make up 1 main unit. e.g. ₹1 = 100 paise
// Number of fractional units that make up 1 unit of the main value
FUShare uint
// PrefixSymbol if true will prefix the symbol when stringified
PrefixSymbol bool
// SuffixSymbol if true will suffix the symbol when stringified
SuffixSymbol bool
}
```### New(main int, fractional int, code, symbol string, funame string, fushare uint)
New returns a pointer of currency instance created based on the configuration.
```
main - Main/Super unit of the currency
fractional - Subunit/fractional unit of the currency
code - is the currency code according to [ISO 4217 specification](https://en.wikipedia.org/wiki/ISO_4217)
symbol - Unicode symbol of the currency
funame - Name of the fractional/sub unit
fushare - Number of fractional/sub units that make up 1 unit of the main/super unit
```_IMPORTANT! Fractional unit can be negative only when the main value is 0. If the main value is not 0, fractional unit's negative sign is ignored._
### Parsers & convenience methods
1. `NewFractional(fractional int, symbol string, fulabel string, fushare uint)` returns a currency struct instance, given a currency's total value represented by the fractional unit
2. `ParseString(value string, code, symbol string, fulabel string, fushare uint)` returns a currency struct instance, given a currency value represented as string
3. `ParseFloat64(value float64, code, symbol string, funame string, fushare uint)` returns a currency struct instance, given a currency value represented in float64### Computational methods
IMPORTANT: Computation is supported only between same type of currencies (i.e. currency codes _*must*_ match)
1. `c1.Add(c2 currency)` add c2 to c1, and update c1
2. `c1.AddInt(main int, fractional int)` add the currency equivalent of the main & fractional int to c1
3. `c1.Subtract(c2 currency)` subtract c2 from c1, and update c1
4. `c1.SubtractIn(main int, fractional int)` subtract the currency equivalent of the main & fractional int from c1
5. `c1.Multiply(n int)` multiply c1 by n, where n is an integer
6. `c1.MultiplyFloat64(n float64)` multiply c1 by n, where n is a float64 value
7. `c1.UpdateWithFractional(ftotal int)` would update the the value of c1, where _ftotal_ is the total value of the currency in fractional unit. e.g. INR, `UpdateWithFractional(100)` would set the main value as `1` and fractional unit as `0`
8. `c1.FractionalTotal() int` returns the total value of the currency in its fractional unit. e.g. INR, if the Main value is `1` and fractional unit is `0`, it would return `100`, i.e. 100 paise
9. `c1.Percent(n float64) currency` returns a new currency instance which is n percentage of c1
10. `c1.Allocate(n int, retain bool)[]currency, ok ` returns a slice of currency of size n. `ok` if **true** means the currency value is fully divisible by n. If `retain` is true,
then `c1` will have the remainder value after allocation, otherwise the remainder is distributed among the returned currencies.#### Why does `Allocate(n int, retain bool)` return a slice of currencies?
`Allocate` unlike other operations, cannot be rounded off. If it is rounded, it would result in currency _peddling_.
e.g. ₹1/- (INR 1) is to be divided by 3. There are 2 options of dividing this by 3.
1. Set 33 paise per split, and retain the remaining 1 paise at source. (`Divide(n, true)`)
2. Set 1 of the split with an extra value, i.e. 34 + 33 + 33. (`Divide(n, false)`)
### Multiple currency representations
1. `c1.String()`, returns a string representation of the currency value
2. `c1.Float64()`, returns a float64 representation of the currency value## Benchmarks
How to run?
`$ go test -bench=.`
Results when run on a MacBook Pro (13-inch, M3, 2024), CPU: Apple M3, RAM: 24 GB
```
go version go1.23.1 darwin/arm64
github.com/naughtygopher/currency [allocate]$ go test -bench .
goos: darwin
goarch: arm64
pkg: github.com/naughtygopher/currency/v2
cpu: Apple M3
BenchmarkNew-8 55541650 21.68 ns/op
BenchmarkNewFractional-8 58322852 21.69 ns/op
BenchmarkParseFloat64-8 47724391 25.72 ns/op
BenchmarkParseString-8 6650085 182.2 ns/op
BenchmarkString-8 20838006 58.65 ns/op
BenchmarkStringNoPrefix-8 30418314 39.87 ns/op
BenchmarkFloat64-8 1000000000 0.2722 ns/op
BenchmarkFractionalTotal-8 1000000000 0.2697 ns/op
BenchmarkUpdateWithFractional-8 1000000000 1.068 ns/op
BenchmarkAdd-8 190538139 6.245 ns/op
BenchmarkAddInt-8 230544486 5.690 ns/op
BenchmarkSubtract-8 185860339 6.537 ns/op
BenchmarkSubtractInt-8 217542852 5.571 ns/op
BenchmarkMultiply-8 282455095 4.335 ns/op
BenchmarkMultiplyFloat64-8 84543258 13.13 ns/op
BenchmarkPercent-8 52612252 21.28 ns/op
BenchmarkAllocate-8 35645416 34.41 ns/op
PASS
ok github.com/naughtygopher/currency/v2 23.125s
```## References
1. [Ref - Sub unit or fractional unit]()
2. [Ref - Currencies](https://en.wikipedia.org/wiki/Currency) - about currencies
3. [Non-decimal sub unit in currencies are only used by 2 countries today](https://en.wikipedia.org/wiki/Non-decimal_currency). These are getting phased out._IMPORTANT! This package does not support sub units which are not a power of 10. Nor does it support currencies with more than 1 sub unit_
## The gopher
The gopher used here was created using [Gopherize.me](https://gopherize.me/). Deal with currency professionally just like this gopher!