tomath

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2020 License: MIT Imports: 5 Imported by: 0

README

toMath

toMath is a wrapper library for shopspring/decimal, an arbitrary-precision fixed-point decimal numbers in go, where you can create a Decimal, run operations on it, and output the math underlying those operations.

Install

go get github.com/cbelsole/tomath

Requirements

Decimal library requires Go version >=1.7

Usage

package main

import (
	"github.com/cbelsole/tomath"
	"github.com/stretchr/testify/assert"
)

func main() {
	d := tomath.NewFromFloatWithName("var1", 1.1).
		Round(1).
		Add(tomath.NewFromFloatWithName("var2", 1)).
		Add(tomath.NewFromFloatWithName("var2", 1)).
		Div(tomath.NewFromFloatWithName("var3", 2)).
		Mul(tomath.NewFromFloatWithName("var4", 2)).
		SetName("var5")

	vars, formula := d.Math()
	assert.Equal(t, "(round(1)(var1) + var2 + var2) / var3 * var4 = var5", vars)
	assert.Equal(t, "(round(1)(1.1) + 1 + 1) / 2 * 2 = 3.1", formula)

	d = d.Resolve().Add(timesOneHundred(tomath.NewFromFloatWithName("var6", 3))).SetName("var7")
	vars, formula = d.Math()
	assert.Equal(t, "var5 + var6TimesOneHundred = var7", vars)
	assert.Equal(t, "3.1 + 300 = 303.1", formula)
}

func timesOneHundred(input tomath.Decimal) tomath.Decimal {
	oneHundred := tomath.NewFromFloatWithName("OneHundred", 100)
	return input.Mul(oneHundred).ResolveTo(input.GetName() + "Times" + oneHundred.GetName())
}
Notes
  • toMath makes no assertions on Decimal names. Use ()+-*/^%= characters at your own risk.

Documentation

pkg.go.dev/github.com/cbelsole/tomath

License

The MIT License (MIT)

shopspring/decimal - The MIT License (MIT)

fpd.Decimal - The MIT License (MIT)

Documentation

Overview

Package tomath wraps github.com/shopspring/decimal library which implements an arbitrary precision fixed-point decimal.

The zero-value of a Decimal is 0, as you would expect. The zero-value name is "?". To set a name for a decimal without a name use the SetName() method.

The best way to create a new Decimal is to use decimal.NewFromStringWithName, ex:

n, err := decimal.NewFromStringWithName("var1", "1.3")
n.String() // output: "3.1"

vars, formula := n.Add("var2", "1.8")
                  .SetName("var3")
                  .Math()
// vars:    "var1 + var2 = var3"
// formula: "1.3 + 1.8 = 3.1"

To use Decimal as part of a struct:

type Struct struct {
    Number Decimal
}

Note: This can "only" represent numbers with a maximum of 2^31 digits after the decimal point.

Index

Constants

This section is empty.

Variables

View Source
var (
	Zero = Decimal{
		// contains filtered or unexported fields
	}
)

Functions

func RescalePair

func RescalePair(d1 Decimal, d2 Decimal) (Decimal, Decimal)

RescalePair rescales two decimals to common exponential value (minimal exp of both decimals)

Types

type Decimal

type Decimal struct {
	// contains filtered or unexported fields
}

Decimal represents a fixed-point decimal. It is immutable. number = value * 10 ^ exp

func Avg

func Avg(first Decimal, rest ...Decimal) Decimal

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

func Max

func Max(first Decimal, rest ...Decimal) Decimal

Max returns the largest Decimal 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(first Decimal, rest ...Decimal) Decimal

Min returns the smallest Decimal 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 New

func New(value int64, exp int32) Decimal

New returns a new fixed-point decimal, value * 10 ^ exp.

func NewFromBigInt

func NewFromBigInt(value *big.Int, exp int32) Decimal

NewFromBigInt returns a new Decimal from a big.Int, value * 10 ^ exp

func NewFromBigIntWithName

func NewFromBigIntWithName(name string, value *big.Int, exp int32) Decimal

NewFromBigIntWithName returns a new Decimal from a big.Int, value * 10 ^ exp with a given name

func NewFromDecimal

func NewFromDecimal(d decimal.Decimal) Decimal

NewFromDecimal returns a new Decimal from github.com/shopspring/decimal#Decimal.

func NewFromDecimalWithName

func NewFromDecimalWithName(name string, d decimal.Decimal) Decimal

NewFromDecimalWithName returns a new Decimal from github.com/shopspring/decimal#Decimal with a given name.

func NewFromFloat

func NewFromFloat(value float64) Decimal

NewFromFloat converts a float64 to Decimal.

The converted number will contain the number of significant digits that can be represented in a float with reliable roundtrip. This is typically 15 digits, but may be more in some cases. See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.

For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.

NOTE: this will panic on NaN, +/-inf

func NewFromFloat32

func NewFromFloat32(value float32) Decimal

NewFromFloat32 converts a float32 to Decimal.

The converted number will contain the number of significant digits that can be represented in a float with reliable roundtrip. This is typically 6-8 digits depending on the input. See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.

For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.

NOTE: this will panic on NaN, +/-inf

func NewFromFloat32WithName

func NewFromFloat32WithName(name string, value float32) Decimal

NewFromFloat32WithName converts a float32 to Decimal with a given name.

The converted number will contain the number of significant digits that can be represented in a float with reliable roundtrip. This is typically 6-8 digits depending on the input. See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.

For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.

NOTE: this will panic on NaN, +/-inf

func NewFromFloatWithExponent

func NewFromFloatWithExponent(value float64, exp int32) Decimal

NewFromFloatWithExponent converts a float64 to Decimal, with an arbitrary number of fractional digits.

Example:

NewFromFloatWithExponent(123.456, -2).String() // output: "123.46"

func NewFromFloatWithExponentWithName

func NewFromFloatWithExponentWithName(name string, value float64, exp int32) Decimal

NewFromFloatWithExponentWithName converts a float64 to Decimal with a given name, with an arbitrary number of fractional digits.

Example:

NewFromFloatWithExponentWithName("var1", 123.456, -2).String() // output: "123.46"

func NewFromFloatWithName

func NewFromFloatWithName(name string, value float64) Decimal

NewFromFloatWithName converts a float64 to Decimal with a given name.

The converted number will contain the number of significant digits that can be represented in a float with reliable roundtrip. This is typically 15 digits, but may be more in some cases. See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.

For slightly faster conversion, use NewFromFloatWithNameWithExponent where you can specify the precision in absolute terms.

NOTE: this will panic on NaN, +/-inf

func NewFromInt

func NewFromInt(value int64) Decimal

NewFromInt converts a int64 to Decimal.

Example:

NewFromInt(123).String() // output: "123"
NewFromInt(-10).String() // output: "-10"

func NewFromInt32

func NewFromInt32(value int32) Decimal

NewFromInt32 converts a int32 to Decimal.

Example:

NewFromInt(123).String() // output: "123"
NewFromInt(-10).String() // output: "-10"

func NewFromInt32WithName

func NewFromInt32WithName(name string, value int32) Decimal

NewFromInt32WithName converts a int32 to Decimal with a given name.

Example:

NewFromInt32WithName("var1", 123).String() // output: "123"
NewFromInt32WithName("var1", -10).String() // output: "-10"

func NewFromIntWithName

func NewFromIntWithName(name string, value int64) Decimal

NewFromIntWithName converts a int64 to Decimal with a given name.

Example:

NewFromIntWithName("var1", 123).String() // output: "123"
NewFromIntWithName("var1", -10).String() // output: "-10"

func NewFromString

func NewFromString(value string) (Decimal, error)

NewFromString returns a new Decimal from a string representation. Trailing zeroes are not trimmed.

Example:

d, err := NewFromString("-123.45")
d2, err := NewFromString(".0001")
d3, err := NewFromString("1.47000")

func NewFromStringWithName

func NewFromStringWithName(name string, value string) (Decimal, error)

NewFromStringWithName returns a new Decimal from a string representation with a given name. Trailing zeroes are not trimmed.

Example:

d, err := NewFromStringWithName("var1", "-123.45")
d2, err := NewFromStringWithName("var1", ".0001")
d3, err := NewFromStringWithName("var1", "1.47000")

func NewWithName

func NewWithName(name string, value int64, exp int32) Decimal

NewWithName returns a new fixed-point decimal, value * 10 ^ exp with a given name.

func RequireFromString

func RequireFromString(value string) Decimal

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

Example:

d := RequireFromString("-123.45")
d2 := RequireFromString(".0001")

func RequireFromStringWithName

func RequireFromStringWithName(name string, value string) Decimal

RequireFromStringWithName returns a new Decimal from a string representation with a given name or panics if NewFromString would have returned an error.

Example:

d := RequireFromStringWithName("var1", "-123.45")
d2 := RequireFromStringWithName("var1", ".0001")

func Sum

func Sum(first Decimal, rest ...Decimal) Decimal

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

func (Decimal) Abs

func (d Decimal) Abs() Decimal

Abs returns the absolute value of the decimal.

func (Decimal) Add

func (d Decimal) Add(d2 Decimal) Decimal

Add returns d + d2.

func (Decimal) Atan

func (d Decimal) Atan() Decimal

Atan returns the arctangent, in radians, of x.

func (Decimal) BigFloat

func (d Decimal) BigFloat() *big.Float

BigFloat returns decimal as BigFloat. Be aware that casting decimal to BigFloat might cause a loss of precision.

func (Decimal) BigInt

func (d Decimal) BigInt() *big.Int

BigInt returns integer component of the decimal as a BigInt.

func (Decimal) Ceil

func (d Decimal) Ceil() Decimal

Ceil returns the nearest integer value greater than or equal to d.

func (Decimal) Cmp

func (d Decimal) Cmp(d2 Decimal) int

Cmp compares the numbers represented by d and d2 and returns:

-1 if d <  d2
 0 if d == d2
+1 if d >  d2

func (Decimal) Coefficient

func (d Decimal) Coefficient() *big.Int

Coefficient returns the coefficient of the decimal. It is scaled by 10^Exponent()

func (Decimal) Cos

func (d Decimal) Cos() Decimal

Cos returns the cosine of the radian argument x.

func (Decimal) Decimal

func (d Decimal) Decimal() decimal.Decimal

Decimal ejects the github.com/shopspring/decimal#Decimal

func (Decimal) Div

func (d Decimal) Div(d2 Decimal) Decimal

Div returns d / d2. If it doesn't divide exactly, the result will have DivisionPrecision digits after the decimal point.

func (Decimal) DivRound

func (d Decimal) DivRound(d2 Decimal, precision int32) Decimal

DivRound divides and rounds to a given precision i.e. to an integer multiple of 10^(-precision)

for a positive quotient digit 5 is rounded up, away from 0
if the quotient is negative then digit 5 is rounded down, away from 0

Note that precision<0 is allowed as input.

func (Decimal) Equal

func (d Decimal) Equal(d2 Decimal) bool

Equal returns whether the numbers represented by d and d2 are equal.

func (Decimal) Equals

func (d Decimal) Equals(d2 Decimal) bool

Equals is deprecated, please use Equal method instead

func (Decimal) Exponent

func (d Decimal) Exponent() int32

Exponent returns the exponent, or scale component of the decimal.

func (Decimal) Float64

func (d Decimal) Float64() (f float64, exact bool)

Float64 returns the nearest float64 value for d and a bool indicating whether f represents d exactly. For more details, see the documentation for big.Rat.Float64

func (Decimal) Floor

func (d Decimal) Floor() Decimal

Floor returns the nearest integer value less than or equal to d.

func (Decimal) GetName

func (d Decimal) GetName() string

SetName gets the name of the Decimal

func (*Decimal) GobDecode

func (d *Decimal) GobDecode(data []byte) error

GobDecode implements the gob.GobDecoder interface for gob serialization.

func (Decimal) GobEncode

func (d Decimal) GobEncode() ([]byte, error)

GobEncode implements the gob.GobEncoder interface for gob serialization.

func (Decimal) GreaterThan

func (d Decimal) GreaterThan(d2 Decimal) bool

GreaterThan (GT) returns true when d is greater than d2.

func (Decimal) GreaterThanOrEqual

func (d Decimal) GreaterThanOrEqual(d2 Decimal) bool

GreaterThanOrEqual (GTE) returns true when d is greater than or equal to d2.

func (Decimal) IntPart

func (d Decimal) IntPart() int64

IntPart returns the integer component of the decimal.

func (Decimal) IsNegative

func (d Decimal) IsNegative() bool

IsNegative return

true if d < 0
false if d == 0
false if d > 0

func (Decimal) IsPositive

func (d Decimal) IsPositive() bool

IsPositive return

true if d > 0
false if d == 0
false if d < 0

func (Decimal) IsZero

func (d Decimal) IsZero() bool

IsZero return

true if d == 0
false if d > 0
false if d < 0

func (Decimal) LessThan

func (d Decimal) LessThan(d2 Decimal) bool

LessThan (LT) returns true when d is less than d2.

func (Decimal) LessThanOrEqual

func (d Decimal) LessThanOrEqual(d2 Decimal) bool

LessThanOrEqual (LTE) returns true when d is less than or equal to d2.

func (Decimal) MarshalBinary

func (d Decimal) MarshalBinary() (data []byte, err error)

MarshalBinary implements the encoding.BinaryMarshaler interface.

func (Decimal) MarshalJSON

func (d Decimal) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (Decimal) MarshalText

func (d Decimal) MarshalText() (text []byte, err error)

MarshalText implements the encoding.TextMarshaler interface for XML serialization.

func (Decimal) Math

func (d Decimal) Math() (string, string)

Math returns two strings representing the formula underlying the decimal. The first uses the decimal names. The second uses the decimal values. Both are follwed by an equals sign with the current name and value respectively.

func (Decimal) Mod

func (d Decimal) Mod(d2 Decimal) Decimal

Mod returns d % d2.

func (Decimal) Mul

func (d Decimal) Mul(d2 Decimal) Decimal

Mul returns d * d2.

func (Decimal) Neg

func (d Decimal) Neg() Decimal

Neg returns -d.

func (Decimal) Pow

func (d Decimal) Pow(d2 Decimal) Decimal

Pow returns d to the power d2

func (Decimal) QuoRem

func (d Decimal) QuoRem(d2 Decimal, precision int32) (Decimal, Decimal)

QuoRem does divsion with remainder d.QuoRem(d2,precision) returns quotient q and remainder r such that

d = d2 * q + r, q an integer multiple of 10^(-precision)
0 <= r < abs(d2) * 10 ^(-precision) if d>=0
0 >= r > -abs(d2) * 10 ^(-precision) if d<0

Note that precision<0 is allowed as input.

func (Decimal) Rat

func (d Decimal) Rat() *big.Rat

Rat returns a rational number representation of the decimal.

func (Decimal) Resolve

func (d Decimal) Resolve() Decimal

Resolve removes the underlying math from the decimal and replaces it with the current name and value.

func (Decimal) ResolveTo

func (d Decimal) ResolveTo(name string) Decimal

ResolveTo is a wrapper around SetName() and Resolve().

func (Decimal) Round

func (d Decimal) Round(places int32) Decimal

Round rounds the decimal to places decimal places. If places < 0, it will round the integer part to the nearest 10^(-places).

Example:

NewFromFloat(5.45).Round(1).String() // output: "5.5"
NewFromFloat(545).Round(-1).String() // output: "550"

func (Decimal) RoundBank

func (d Decimal) RoundBank(places int32) Decimal

RoundBank rounds the decimal to places decimal places. If the final digit to round is equidistant from the nearest two integers the rounded value is taken as the even number

If places < 0, it will round the integer part to the nearest 10^(-places).

Examples:

NewFromFloat(5.45).Round(1).String() // output: "5.4"
NewFromFloat(545).Round(-1).String() // output: "540"
NewFromFloat(5.46).Round(1).String() // output: "5.5"
NewFromFloat(546).Round(-1).String() // output: "550"
NewFromFloat(5.55).Round(1).String() // output: "5.6"
NewFromFloat(555).Round(-1).String() // output: "560"

func (Decimal) RoundCash

func (d Decimal) RoundCash(interval uint8) Decimal

RoundCash aka Cash/Penny/öre rounding rounds decimal to a specific interval. The amount payable for a cash transaction is rounded to the nearest multiple of the minimum currency unit available. The following intervals are available: 5, 10, 25, 50 and 100; any other number throws a panic.

  5:   5 cent rounding 3.43 => 3.45
 10:  10 cent rounding 3.45 => 3.50 (5 gets rounded up)
 25:  25 cent rounding 3.41 => 3.50
 50:  50 cent rounding 3.75 => 4.00
100: 100 cent rounding 3.50 => 4.00

For more details: https://en.wikipedia.org/wiki/Cash_rounding

func (*Decimal) Scan

func (d *Decimal) Scan(value interface{}) error

Scan implements the sql.Scanner interface for database deserialization.

func (Decimal) SetName

func (d Decimal) SetName(name string) Decimal

SetName sets the name of the Decimal

func (Decimal) Shift

func (d Decimal) Shift(s int32) Decimal

Shift shifts the decimal in base 10. It shifts left when shift is positive and right if shift is negative. In simpler terms, the given value for shift is added to the exponent of the decimal.

func (Decimal) Sign

func (d Decimal) Sign() int

Sign returns:

-1 if d <  0
 0 if d == 0
+1 if d >  0

func (Decimal) Sin

func (d Decimal) Sin() Decimal

Sin returns the sine of the radian argument x.

func (Decimal) String

func (d Decimal) String() string

String returns the string representation of the decimal with the fixed point.

Example:

d := New(-12345, -3)
println(d.String())

Output:

-12.345

func (Decimal) StringFixed

func (d Decimal) StringFixed(places int32) string

StringFixed returns a rounded fixed-point string with places digits after the decimal point.

Example:

NewFromFloat(0).StringFixed(2) // output: "0.00"
NewFromFloat(0).StringFixed(0) // output: "0"
NewFromFloat(5.45).StringFixed(0) // output: "5"
NewFromFloat(5.45).StringFixed(1) // output: "5.5"
NewFromFloat(5.45).StringFixed(2) // output: "5.45"
NewFromFloat(5.45).StringFixed(3) // output: "5.450"
NewFromFloat(545).StringFixed(-1) // output: "550"

func (Decimal) StringFixedBank

func (d Decimal) StringFixedBank(places int32) string

StringFixedBank returns a banker rounded fixed-point string with places digits after the decimal point.

Example:

NewFromFloat(0).StringFixedBank(2) // output: "0.00"
NewFromFloat(0).StringFixedBank(0) // output: "0"
NewFromFloat(5.45).StringFixedBank(0) // output: "5"
NewFromFloat(5.45).StringFixedBank(1) // output: "5.4"
NewFromFloat(5.45).StringFixedBank(2) // output: "5.45"
NewFromFloat(5.45).StringFixedBank(3) // output: "5.450"
NewFromFloat(545).StringFixedBank(-1) // output: "540"

func (Decimal) StringFixedCash

func (d Decimal) StringFixedCash(interval uint8) string

StringFixedCash returns a Swedish/Cash rounded fixed-point string. For more details see the documentation at function RoundCash.

func (Decimal) StringScaled

func (d Decimal) StringScaled(exp int32) string

StringScaled first scales the decimal then calls .String() on it. NOTE: buggy, unintuitive, and DEPRECATED! Use StringFixed instead.

func (Decimal) Sub

func (d Decimal) Sub(d2 Decimal) Decimal

Sub returns d - d2.

func (Decimal) Tan

func (d Decimal) Tan() Decimal

Tan returns the tangent of the radian argument x.

func (Decimal) Truncate

func (d Decimal) Truncate(precision int32) Decimal

Truncate truncates off digits from the number, without rounding.

NOTE: precision is the last digit that will not be truncated (must be >= 0).

Example:

decimal.NewFromString("123.456").Truncate(2).String() // "123.45"

func (*Decimal) UnmarshalBinary

func (d *Decimal) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. As a string representation is already used when encoding to text, this method stores that string as []byte

func (*Decimal) UnmarshalJSON

func (d *Decimal) UnmarshalJSON(decimalBytes []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

func (*Decimal) UnmarshalText

func (d *Decimal) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface for XML deserialization.

func (Decimal) Value

func (d Decimal) Value() (driver.Value, error)

Value implements the driver.Valuer interface for database serialization.

type NullDecimal

type NullDecimal struct {
	// contains filtered or unexported fields
}

NullDecimal represents a nullable decimal with compatibility for scanning null values from the database.

func (NullDecimal) Decimal

func (d NullDecimal) Decimal() Decimal

func (NullDecimal) MarshalJSON

func (d NullDecimal) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (*NullDecimal) Scan

func (d *NullDecimal) Scan(value interface{}) error

Scan implements the sql.Scanner interface for database deserialization.

func (*NullDecimal) UnmarshalJSON

func (d *NullDecimal) UnmarshalJSON(decimalBytes []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

func (NullDecimal) Valid

func (d NullDecimal) Valid() bool

func (NullDecimal) Value

func (d NullDecimal) Value() (driver.Value, error)

Value implements the driver.Valuer interface for database serialization.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL