Currency package helps you do currency computations accurately. Currency
struct holds all the data required to define a currency.
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 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.
NewFractional(fractional int, symbol string, fulabel string, fushare uint)
returns a currency struct instance, given a currency's total value represented by the fractional unitParseString(value string, code, symbol string, fulabel string, fushare uint)
returns a currency struct instance, given a currency value represented as stringParseFloat64(value float64, code, symbol string, funame string, fushare uint)
returns a currency struct instance, given a currency value represented in float64
IMPORTANT: Computation is supported only between same type of currencies (i.e. currency codes must match)
c1.Add(c2 currency)
add c2 to c1, and update c1c1.AddInt(main int, fractional int)
add the currency equivalent of the main & fractional int to c1c1.Subtract(c2 currency)
subtract c2 from c1, and update c1c1.SubtractIn(main int, fractional int)
subtract the currency equivalent of the main & fractional int from c1c1.Multiply(n int)
multiply c1 by n, where n is an integerc1.MultiplyFloat64(n float64)
multiply c1 by n, where n is a float64 valuec1.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 as1
and fractional unit as0
c1.FractionalTotal() int
returns the total value of the currency in its fractional unit. e.g. INR, if the Main value is1
and fractional unit is0
, it would return100
, i.e. 100 paisec1.Percent(n float64) currency
returns a new currency instance which is n percentage of c1c1.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. Ifretain
is true, thenc1
will have the remainder value after allocation, otherwise the remainder is distributed among the returned 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)`)
c1.String()
, returns a string representation of the currency valuec1.Float64()
, returns a float64 representation of the currency value
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
- Ref - Sub unit or fractional unit
- Ref - Currencies - about currencies
- Non-decimal sub unit in currencies are only used by 2 countries today. 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 used here was created using Gopherize.me. Deal with currency professionally just like this gopher!