# bps

package
Version: v1.1.1 Latest Latest

Go to latest
Published: May 25, 2021 License: MIT

## Documentation ¶

### Overview ¶

Handling floating point numbers in programming causes rounding errors. To avoid this, all numerical calculations are done using basis points (integer only) in this package.

Example
```package main

import (
"fmt"

"go.mercari.io/go-bps/bps"
)

type Bill struct {
Principal int64
Rate      *bps.BPS
}

func NewBill(principal int64, rate *bps.BPS) *Bill {
return &Bill{Principal: principal, Rate: rate}
}

// CalcInterestFee calculates an interest fee for `b`
func (b *Bill) CalcInterestFee() *bps.BPS {
return b.Rate.Mul(b.Principal)
}

type Bills []*Bill

func (bl Bills) CalcInterestFee() *bps.BPS {
var fees []*bps.BPS
for _, b := range bl {
fees = append(fees, b.CalcInterestFee())
}
return bps.Sum(bps.NewFromAmount(0), fees...)
}

func main() {
// principal amount is 14999
var principal int64 = 14999
// interest rate is 8.0%
rate1 := bps.NewFromPercentage(8)
// interest rate is 2.645% = 264.5 basis points = 2645 deci basis points
rate2 := bps.NewFromDeciBasisPoint(2645)
// interest rate is 4.5%
rate3 := bps.MustFromString(".045")

b1 := NewBill(principal, rate1)
b2 := NewBill(principal, rate2)
b3 := NewBill(principal, rate3)
bills := Bills{b1, b2, b3}

// interest fee: 14999 * 8% = 1199.92
// Amounts() returns fee amount as integer that's rounded off decimal floating point
fmt.Println(b1.CalcInterestFee().FloatString(2))
// interest fee: 14999 * 2.645 = 396.72355
fmt.Println(b2.CalcInterestFee().FloatString(2))
// interest fee: 14999 * 4.5% = 674.955
fmt.Println(b3.CalcInterestFee().FloatString(2))
// sum interest fees: 1199.92 + 396.72355 + 674.955 = 2271.59855
// not equal 1199 + 396 + 674 = 2269
fmt.Println(bills.CalcInterestFee().FloatString(0))
}
```
```Output:

1199.92
396.72
674.96
2272
```

### Constants ¶

View Source
```const (
PPB unit = iota + 1
PPM
DeciBasisPoint
HalfBasisPoint
BasisPoint
Percentage
)```

List of values that `unit` can take.

View Source
```const (
DenomPPM            int64 = 1000
DenomDeciBasisPoint       = DenomPPM * 10
DenomHalfBasisPoint       = DenomDeciBasisPoint * 5
DenomBasisPoint           = DenomHalfBasisPoint * 2
DenomPercentage           = DenomBasisPoint * 100
DenomAmount               = DenomPercentage * 100
)```

Denominators for each parts

### Variables ¶

View Source
`var BaseUnit = DeciBasisPoint`

BaseUnit is unit to display *BPS as string via String method. Default is DeciBasisPoint unit, you can update this. But it should be used consistent value in your application.

### Functions ¶

This section is empty.

### Types ¶

#### type BPS ¶

```type BPS struct {
// contains filtered or unexported fields
}```

#### func Avg ¶

`func Avg(first *BPS, rest ...*BPS) *BPS`

Avg returns the average value of the provided first and rest BPS

#### func Max ¶

`func Max(first *BPS, rest ...*BPS) *BPS`

Max returns the largest BPS that was passed in the arguments.

To call this function with an array, you must do:

```Max(arr[0], arr[1:]...)
```

This makes it harder to accidentally call Max with 0 arguments.

#### func Min ¶

`func Min(fisrt *BPS, rest ...*BPS) *BPS`

Min returns the smallest BPS that was passed in the arguments.

To call this function with an array, you must do:

```Min(arr[0], arr[1:]...)
```

This makes it harder to accidentally call Min with 0 arguments.

#### func MustFromString ¶

`func MustFromString(value string) *BPS`

MustFromString returns a new BPS from a string representation or panics if NewFromString would have returned an error.

Example
```package main

import (
"fmt"

"go.mercari.io/go-bps/bps"
)

func main() {
// 15%
b1 := bps.MustFromString("0.15")
fmt.Println(b1.Percentages())
// 2.645% = 264.5 basis points
b2 := bps.MustFromString("0.02645")
fmt.Println(b2.DeciBasisPoints())

a := bps.NewFromAmount(1e12)
b, _ := bps.NewFromString(".000001") // 1 / 1e6
// Set PPM as BaseUnit to show value as ppm
bps.BaseUnit = bps.PPM
// teardown
bps.BaseUnit = bps.DeciBasisPoint

n := bps.NewFromAmount(0)
for i := 0; i < 1000; i++ {
}
fmt.Println(n.Amounts())
}
```
```Output:

15
2645
1000000000000000001 ppm
10
```

#### func NewFromAmount ¶

`func NewFromAmount(amt int64) *BPS`

NewFromAmount makes new BPS instance from real amount

#### func NewFromBaseUnit ¶

`func NewFromBaseUnit(v int64) *BPS`

NewFromBaseUnit makes new BPS instance from BaseUnit value. That means the effective digits is modifiable by BaseUnit.

Example
```package main

import (
"fmt"

"go.mercari.io/go-bps/bps"
)

func main() {
// backup
u := bps.BaseUnit
var arg int64 = 15

// The default BaseUnit is DeciBasisPoint
deci := bps.NewFromBaseUnit(arg)
fmt.Println(deci.PPMs())

// BaseUnit is updated by PPB
bps.BaseUnit = bps.PPB
ppb := bps.NewFromBaseUnit(arg)
fmt.Println(ppb.PPBs())

// BaseUnit is updated by PPM
bps.BaseUnit = bps.PPM
ppm := bps.NewFromBaseUnit(arg)
fmt.Println(ppm.PPBs())

// BaseUnit is updated by HalfBasisPoint
bps.BaseUnit = bps.HalfBasisPoint
hbp := bps.NewFromBaseUnit(arg)
fmt.Println(hbp.PPBs())

// BaseUnit is updated by BasisPoint
bps.BaseUnit = bps.BasisPoint
bp := bps.NewFromBaseUnit(arg)
fmt.Println(bp.PPBs())

// BaseUnit is updated by Percentage
bps.BaseUnit = bps.Percentage
p := bps.NewFromBaseUnit(arg)
fmt.Println(p.PPBs())

// teardown
bps.BaseUnit = u
}
```
```Output:

150
15
15000
750000
1500000
150000000
```

#### func NewFromBasisPoint ¶

`func NewFromBasisPoint(bp int64) *BPS`

NewFromBasisPoint makes new BPS instance from basis point

#### func NewFromDeciBasisPoint ¶

`func NewFromDeciBasisPoint(deci int64) *BPS`

NewFromDeciBasisPoint makes new BPS instance from deci basis point

#### func NewFromHalfBasisPoint ¶

`func NewFromHalfBasisPoint(bp int64) *BPS`

NewFromHalfBasisPoint makes new BPS instance from half basis point

#### func NewFromPPB ¶ added in v1.1.0

`func NewFromPPB(ppb *big.Int) *BPS`

NewFromPPB makes new BPS instance from part per billion(ppb)

#### func NewFromPPM ¶

`func NewFromPPM(ppm *big.Int) *BPS`

NewFromPPM makes new BPS instance from part per million(ppm)

#### func NewFromPercentage ¶

`func NewFromPercentage(per int64) *BPS`

NewFromPercentage makes new BPS instance from percentage

#### func NewFromString ¶

`func NewFromString(value string) (*BPS, error)`

NewFromString returns a new BPS from a string representation.

Example
```package main

import (
"fmt"

"go.mercari.io/go-bps/bps"
)

func main() {
// 15%
b1, _ := bps.NewFromString("0.15")
fmt.Println(b1.Percentages())
// 2.645% = 264.5 basis points
b2, _ := bps.NewFromString("0.02645")
fmt.Println(b2.DeciBasisPoints())
}
```
```Output:

15
2645
```

#### func Sum ¶

`func Sum(first *BPS, rest ...*BPS) *BPS`

Sum returns the combined total of the provided first and rest BPS

#### func (*BPS) Abs ¶

`func (b *BPS) Abs() *BPS`

Abs returns the absolute value of the decimal.

`func (b *BPS) Add(b2 *BPS) *BPS`

#### func (*BPS) Amounts ¶

`func (b *BPS) Amounts() int64`

Amounts returns the basis point as an integer amount.

#### func (*BPS) BaseUnitAmounts ¶

`func (b *BPS) BaseUnitAmounts() *big.Int`

BaseUnitAmounts returns amount representation of BaseUnit as generated. That means the effective digits is modifiable by BaseUnit.

Example
```package main

import (
"fmt"

"go.mercari.io/go-bps/bps"
)

func main() {
// backup
u := bps.BaseUnit
// 15%
b := bps.NewFromPercentage(15)

// The default BaseUnit is DeciBasisPoint
fmt.Println(b.BaseUnitAmounts())

// BaseUnit is updated by PPB
bps.BaseUnit = bps.PPB
fmt.Println(b.BaseUnitAmounts())

// BaseUnit is updated by PPM
bps.BaseUnit = bps.PPM
fmt.Println(b.BaseUnitAmounts())

// BaseUnit is updated by HalfBasisPoint
bps.BaseUnit = bps.HalfBasisPoint
fmt.Println(b.BaseUnitAmounts())

// BaseUnit is updated by BasisPoint
bps.BaseUnit = bps.BasisPoint
fmt.Println(b.BaseUnitAmounts())

// BaseUnit is updated by Percentage
bps.BaseUnit = bps.Percentage
fmt.Println(b.BaseUnitAmounts())

// teardown
bps.BaseUnit = u
}
```
```Output:

15000
150000000
150000
3000
1500
15
```

#### func (*BPS) BasisPoints ¶

`func (b *BPS) BasisPoints() *big.Int`

BasisPoints returns the basis point as an integer basis point count.

#### func (*BPS) Cmp ¶

`func (b *BPS) Cmp(b2 *BPS) int`

#### func (*BPS) DeciBasisPoints ¶

`func (b *BPS) DeciBasisPoints() *big.Int`

DeciBasisPoints returns the basis point as an integer half basis point count.

#### func (*BPS) Div ¶

`func (b *BPS) Div(i int64) *BPS`

Div returns b / i, rounded down to ppm.

#### func (*BPS) Equal ¶

`func (b *BPS) Equal(b2 *BPS) bool`

#### func (*BPS) Float64 ¶

`func (b *BPS) Float64() (f float64, exact bool)`

Float64 returns the nearest float64 value for `b` and a bool indicating whether f represents `b` exactly. If the magnitude of `b` is too large to be represented by a float64, f is an infinity and exact is false. The sign of f always matches the sign of `b`, even if f == 0.

#### func (*BPS) FloatString ¶

`func (b *BPS) FloatString(prec int) string`

FloatString returns the string representation of the amount as generated by *big.Rat.FloatString(prec)

#### func (*BPS) HalfBasisPoints ¶

`func (b *BPS) HalfBasisPoints() *big.Int`

HalfBasisPoints returns the basis point as an integer half basis point count.

#### func (*BPS) IsZero ¶

`func (b *BPS) IsZero() bool`

#### func (*BPS) Mul ¶

`func (b *BPS) Mul(i int64) *BPS`

Mul returns b * i.

#### func (*BPS) Neg ¶

`func (b *BPS) Neg() *BPS`

Neg returns -b.

#### func (*BPS) PPBs ¶ added in v1.1.0

`func (b *BPS) PPBs() *big.Int`

PPBs returns the row value that means PPB.

#### func (*BPS) PPMs ¶

`func (b *BPS) PPMs() *big.Int`

PPMs returns the row value that means PPM.

#### func (*BPS) Percentages ¶

`func (b *BPS) Percentages() *big.Int`

Percentages returns the basis point as an integer percentage count.

#### func (*BPS) Rat ¶

`func (b *BPS) Rat() *big.Rat`

Rat returns a rational number representation of `b`.

#### func (*BPS) Scan ¶

`func (b *BPS) Scan(value interface{}) error`

Scan implements the sql.Scanner interface for database deserialization.

#### func (*BPS) String ¶

`func (b *BPS) String() string`

String returns the string representation of BaseUnit as generated by *big.Int.String(). That means the effective digits is modifiable by BaseUnit.

#### func (*BPS) Sub ¶

`func (b *BPS) Sub(b2 *BPS) *BPS`

Sub returns b - b2.

#### func (*BPS) UnmarshalText ¶ added in v1.1.1

`func (b *BPS) UnmarshalText(text []byte) error`

UnmarshalText implements the encoding.TextUnmarshaler interface.

#### func (*BPS) Value ¶

`func (b *BPS) Value() (driver.Value, error)`

Value implements the driver.Valuer interface for database serialization.