README
¶
Currency
Currency package helps you do currency computations accurately, by avoiding peddling.
The 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
}
New(main int, fractional int, code, symbol string, funame string, fushare uint)
New returns a pointer of currency instance created based on the values provided
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
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
Computational methods
IMPORTANT: Computation is supported only between same type of currencies (i.e. currency codes should be same)
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.Divide(n int, retain bool)[]currency, ok
returns a slice of currency of size n.ok
if returned astrue
means the currency value was perfectly divisible by n. Ifretain
is true, thenc1
will have the remainder value after dividing otherwise it is distributed among the returned currencies.
Why does Divide(n int, retain bool)
return a slice of currencies?
Divide
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
c1.String(prefixSymbol bool)
, returns a string representation of the currency value. Returns string prefixed by its respective symbol ifprefixSymbol
is truec1.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, Early 2015), CPU: 2.7 GHz Intel Core i5, RAM: 8 GB 1867 MHz DDR3, Graphics: Intel Iris Graphics 6100 1536 MB
BenchmarkNew-4 20000000 67.3 ns/op
BenchmarkNewFractional-4 20000000 65.9 ns/op
BenchmarkParseFloat64-4 20000000 87.4 ns/op
BenchmarkParseString-4 3000000 544 ns/op
BenchmarkString-4 10000000 211 ns/op
BenchmarkStringNoPrefix-4 10000000 164 ns/op
BenchmarkFloat64-4 2000000000 0.34 ns/op
BenchmarkFractionalTotal-4 2000000000 0.33 ns/op
BenchmarkUpdateWithFractional-4 100000000 10.3 ns/op
BenchmarkAdd-4 100000000 20.8 ns/op
BenchmarkAddInt-4 100000000 18.9 ns/op
BenchmarkSubtract-4 100000000 21.2 ns/op
BenchmarkSubtractInt-4 100000000 18.3 ns/op
BenchmarkMultiply-4 100000000 16.2 ns/op
BenchmarkMultiplyFloat64-4 50000000 30.1 ns/op
BenchmarkPercent-4 20000000 67.1 ns/op
BenchmarkDivide-4 10000000 155 ns/op
References
- 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
Documentation
¶
Overview ¶
Package currency helps represent a currency with high precision, and do currency computations.
Index ¶
- Variables
- type Currency
- func New(main int, fractional int, code, symbol, funame string, fushare uint) (*Currency, error)
- func NewFractional(ftotal int, code, symbol, funame string, fushare uint) (*Currency, error)
- func ParseFloat64(value float64, code, symbol, funame string, fushare uint) (*Currency, error)
- func ParseString(value string, code, symbol, funame string, fushare uint) (*Currency, error)
- func (c *Currency) Add(acur Currency) error
- func (c *Currency) AddInt(main int, frac int)
- func (c *Currency) Divide(by int, retain bool) ([]Currency, bool)
- func (c *Currency) Float64() float64
- func (c *Currency) FractionalTotal() int
- func (c *Currency) Multiply(by int)
- func (c *Currency) MultiplyFloat64(by float64)
- func (c *Currency) Percent(n float64) *Currency
- func (c *Currency) String(prefixSymbol bool) string
- func (c *Currency) Subtract(scur Currency) error
- func (c *Currency) SubtractInt(main int, frac int)
- func (c *Currency) UpdateWithFractional(frac int)
Constants ¶
This section is empty.
Variables ¶
var ( // ErrMismatchCurrency is the error returned if trying to do computation between unmatched currencies ErrMismatchCurrency = errors.New("currencies do not match") // ErrInvalidCurrency is the error returned while trying parse an invalid currency value ErrInvalidCurrency = errors.New("invalid currency value provided") // ErrInvalidFUS is the error returned when Functional unit share is equal to 0 ErrInvalidFUS = errors.New("invalid functional unit share provided") )
Functions ¶
This section is empty.
Types ¶
type Currency ¶
type Currency struct { // Code represents the international currency code Code string `json:"code,omitempty"` // Symbol is the respective currency symbol Symbol string `json:"symbol,omitempty"` // Main represents the main unit value of the currency Main int `json:"main,omitempty"` // Fractional represents the fractional unit value of the currency Fractional int `json:"fractional,omitempty"` // FUName is the name of the fractional unit of the currency. e.g. paise FUName string `json:"fuName,omitempty"` FUShare uint `json:"fuShare,omitempty"` // contains filtered or unexported fields }
Currency represents money with all the meta data required.
func NewFractional ¶
NewFractional returns a new instance of currency given the total value of currency in fractional unit.
func ParseFloat64 ¶
ParseFloat64 will parse a float value into currency.
func ParseString ¶
ParseString will parse a string representation of the currency and return instance of Currency.
func (*Currency) Divide ¶
Divide divides the currency by the given integer and returns a list of currencies and bool. If `retain` is set as true, the balance will not be distributed among the splits, instead retained inside c. It returns a list because, when the currency cannot be split/divided equally, then the remainder has to be distributed. The bool value if `true`, means the currency was split equally.
func (*Currency) FractionalTotal ¶
FractionalTotal returns the total value in fractional int.
func (*Currency) MultiplyFloat64 ¶
MultiplyFloat64 multiplies the currency by a float value.
func (*Currency) SubtractInt ¶
SubtractInt subtracts main & fractional value provided from the currency
func (*Currency) UpdateWithFractional ¶
UpdateWithFractional will update all the relevant values of currency based on the fractional unit provided.