Version: v1.1.0 Latest Latest Go to latest
Published: Nov 13, 2021 License: MIT

## README ¶ ### Currency v1.0.0

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

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 should be same)

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.Divide(n int, retain bool)[]currency, ok ` returns a slice of currency of size n. `ok` if returned as `true` means the currency value was perfectly divisible by n. If `retain` is true, then `c1` 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

1. `c1.String(prefixSymbol bool)`, returns a string representation of the currency value. Returns string prefixed by its respective symbol if `prefixSymbol` is true
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, 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
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

1. Ref - Sub unit or fractional unit
2. Ref - Currencies - about currencies
3. 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

The gopher used here was created using Gopherize.me. Deal with currency professionally just like this gopher!

## Documentation ¶

### Overview ¶

Package currency helps represent a currency with high precision, and do currency computations.

### Constants ¶

This section is empty.

### Variables ¶

View Source
```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 represents the number of fractional units that make up 1 main unit. e.g. ₹1 = 100 Paise.
FUShare uint `json:"fuShare,omitempty"`
// contains filtered or unexported fields
}```

Currency represents money with all the meta data required.

#### func New ¶

`func New(main int, fractional int, code, symbol, funame string, fushare uint) (*Currency, error)`

New returns a new instance of currency.

#### func NewFractional ¶

`func NewFractional(ftotal int, code, symbol, funame string, fushare uint) (*Currency, error)`

NewFractional returns a new instance of currency given the total value of currency in fractional unit.

#### func ParseFloat64 ¶

`func ParseFloat64(value float64, code, symbol, funame string, fushare uint) (*Currency, error)`

ParseFloat64 will parse a float value into currency.

#### func ParseString ¶

`func ParseString(value string, code, symbol, funame string, fushare uint) (*Currency, error)`

ParseString will parse a string representation of the currency and return instance of Currency.

`func (c *Currency) Add(acur Currency) error`

`func (c *Currency) AddInt(main int, frac int)`

#### func (*Currency) Divide ¶

`func (c *Currency) Divide(by int, retain bool) ([]Currency, bool)`

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) Float64 ¶

`func (c *Currency) Float64() float64`

Float64 returns the currency in float64 format.

#### func (*Currency) Format ¶ added in v1.1.0

`func (c *Currency) Format(s fmt.State, verb rune)`

#### func (*Currency) FractionalTotal ¶

`func (c *Currency) FractionalTotal() int`

FractionalTotal returns the total value in fractional int.

#### func (*Currency) Multiply ¶

`func (c *Currency) Multiply(by int)`

Multiply multiplies the currency by an integer.

#### func (*Currency) MultiplyFloat64 ¶

`func (c *Currency) MultiplyFloat64(by float64)`

MultiplyFloat64 multiplies the currency by a float value.

#### func (*Currency) Percent ¶

`func (c *Currency) Percent(n float64) *Currency`

Percent returns a new instance of currency which is n percent of c.

#### func (*Currency) String ¶

`func (c *Currency) String(prefixSymbol bool) string`

String returns the currency represented as string.

#### func (*Currency) Subtract ¶

`func (c *Currency) Subtract(scur Currency) error`

Subtract subtracts the given currency from the base currency.

#### func (*Currency) SubtractInt ¶

`func (c *Currency) SubtractInt(main int, frac int)`

SubtractInt subtracts main & fractional value provided from the currency

#### func (*Currency) UpdateWithFractional ¶

`func (c *Currency) UpdateWithFractional(frac int)`

UpdateWithFractional will update all the relevant values of currency based on the fractional unit provided.