big

package
v0.58.0 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2024 License: BSD-3-Clause Imports: 8 Imported by: 2

Documentation

Overview

Package big extends the capabilities of standard "math/big" package by adding custom global precision to Float and Rat; and global rounding mode, and bits precision to Float.

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultBitPrecision uint = 128

DefaultBitPrecision define the maximum number of mantissa bits available to represent the value.

In standard library this value is 24 for float32 or 53 for float64.

One should change this value before using the new extended Float in the program.

View Source
var DefaultDigitPrecision = 8

DefaultDigitPrecision define the default number of digits after decimal point which affect the return of String() and MarshalJSON() methods.

A zero value of digit precision mean is it will use the default output of 'f' format.

One should change this value before using the new extended Float or Rat in the program.

View Source
var DefaultRoundingMode = big.ToNearestAway

DefaultRoundingMode define the default rounding mode for all instance of Float.

One should change this value before using the new extended Float in the program.

View Source
var MarshalJSONAsString = true

MarshalJSONAsString define the default return behaviour of MarshalJSON(). If its true (the default) the returned JSON format will encapsulated in double quote, as string instead of as numeric.

Functions

This section is empty.

Types

type Float

type Float struct {
	big.Float
}

Float extend the standard big.Float by setting each instance precision to DefaultBitPrecision, rounding mode to DefaultRoundingMode, and using DefaultDigitPrecision value after decimal point when converted to string.

func AddFloat

func AddFloat(f ...interface{}) *Float

AddFloat return the rounded sum `f[0]+f[1]+...`. It will return nil if the first parameter is not convertable to Float.

func CreateFloat

func CreateFloat(v float64) Float

CreateFloat create Float with default bit precision and rounding mode.

func MulFloat

func MulFloat(f, g interface{}) *Float

MulFloat return the result of multiplication `f*g`. It will return nil if `f` or `g` is not convertible to Float.

func MustParseFloat

func MustParseFloat(s string) (f *Float)

MustParseFloat convert the string `s` into Float or panic.

func NewFloat

func NewFloat(v interface{}) *Float

NewFloat create and initialize new Float with default bit precision, and rounding mode.

func ParseFloat

func ParseFloat(s string) (f *Float, err error)

ParseFloat the string s into Float value.

func QuoFloat

func QuoFloat(f, g interface{}) *Float

QuoFloat return the quotient of `f/g` as new Float.

func SubFloat

func SubFloat(f, g *Float) *Float

SubFloat return the result of subtraction `f-g` as new Float.

func (*Float) Add

func (f *Float) Add(g interface{}) *Float

Add sets f to `f+g` and return the f as the result.

func (*Float) Clone

func (f *Float) Clone() *Float

Clone the instance to new Float.

func (*Float) Int64

func (f *Float) Int64() int64

Int64 return the integer resulting from truncating x towards zero.

func (*Float) IsEqual

func (f *Float) IsEqual(g interface{}) bool

IsEqual will return true if `f == g`.

func (*Float) IsGreater

func (f *Float) IsGreater(g interface{}) bool

IsGreater will return true if `f > g`.

func (*Float) IsGreaterOrEqual

func (f *Float) IsGreaterOrEqual(g interface{}) bool

IsGreaterOrEqual will return true if `f >= g`.

func (*Float) IsLess

func (f *Float) IsLess(g interface{}) bool

IsLess will return true if `f < g`.

func (*Float) IsLessOrEqual

func (f *Float) IsLessOrEqual(g interface{}) bool

IsLessOrEqual will return true if `f <= g`.

func (*Float) IsZero

func (f *Float) IsZero() bool

IsZero will return true if `f == 0`.

func (*Float) MarshalJSON

func (f *Float) MarshalJSON() ([]byte, error)

MarshalJSON implement the json.Marshaler interface and return the output of String method.

func (*Float) Mul

func (f *Float) Mul(g interface{}) *Float

Mul sets f to product of `f * g` and return the result as f. If g is not convertible to Float it will return nil.

func (*Float) ParseFloat

func (f *Float) ParseFloat(s string) (err error)

ParseFloat parse the string into Float value.

func (*Float) Quo

func (f *Float) Quo(g interface{}) *Float

Quo sets f to quotient of `f/g` and return the result as f. If g is not convertible to Float it will return nil.

func (*Float) String

func (f *Float) String() string

String format the Float value into string with maximum mantissa is set by digit precision option.

Unlike standard String method, this method will trim trailing zero digit or decimal point at the end of mantissa.

func (*Float) Sub

func (f *Float) Sub(g interface{}) *Float

Sub sets f to rounded difference `f-g` and return f.

func (*Float) UnmarshalJSON

func (f *Float) UnmarshalJSON(in []byte) (err error)

UnmarshalJSON convert the JSON byte value into Float.

type Int

type Int struct {
	big.Int
}

Int extends the standard big.Int package.

func NewInt

func NewInt(v interface{}) (i *Int)

NewInt create and initialize new Int value from v or nil if v is invalid type that cannot be converted to Int.

func (*Int) Add

func (i *Int) Add(v interface{}) *Int

Add set the i value to i + v and return the i as the result.

func (*Int) IsGreater

func (i *Int) IsGreater(v interface{}) bool

IsGreater will return true if i > v.

func (*Int) IsLess

func (i *Int) IsLess(v interface{}) bool

IsLess will return true if i < v.

func (*Int) IsZero

func (i *Int) IsZero() bool

IsZero will return true if `i == 0`.

func (*Int) MarshalJSON

func (i *Int) MarshalJSON() ([]byte, error)

MarshalJSON implement the json.Marshaler interface and return the output of String method.

If the global variable MarshalJSONAsString is true, the Int value will be encoded as string.

func (*Int) Scan

func (i *Int) Scan(src interface{}) error

Scan implement the database's sql.Scan interface.

func (*Int) UnmarshalJSON

func (i *Int) UnmarshalJSON(in []byte) (err error)

UnmarshalJSON convert the JSON byte value into Int.

func (*Int) Value

func (i *Int) Value() (driver.Value, error)

Value implement the sql/driver.Valuer.

type Rat

type Rat struct {
	big.Rat
}

Rat extend the standard big.Rat using rounding mode ToZero and without panic.

func AddRat

func AddRat(f ...interface{}) *Rat

AddRat return the sum of `f[0]+f[1]+...`. It will return nil if the first parameter is not convertable to Rat.

Example
fmt.Println(AddRat())
fmt.Println(AddRat(nil))
fmt.Println(AddRat("a"))
fmt.Println(AddRat(0, 0.0001))
fmt.Println(AddRat("1.007", "a", "2.003")) // Invalid parameter "a" is ignored.
Output:

0
0
0
0.0001
3.01

func MulRat

func MulRat(f ...interface{}) *Rat

MulRat return the result of multiplication `f[0]*f[1]*...`. It will return nil if the first parameter is not convertable to Rat.

Example
fmt.Println(MulRat())
fmt.Println(MulRat(nil))
fmt.Println(MulRat("a"))
fmt.Println(MulRat(0, 1))
fmt.Println(MulRat(6, "a", "0.3")) // Invalid parameter "a" is ignored.
Output:

0
0
0
0
1.8

func NewRat

func NewRat(v interface{}) (r *Rat)

NewRat create and initialize new Rat value from v. It will return nil if v is not convertable to Rat.

Empty string or empty []byte still considered as valid, and it will return it as zero.

Example
var (
	stdNilInt *big.Int
	stdNilRat *big.Rat
	stdRat    big.Rat
	nilRat    *Rat
)
inputs := []interface{}{
	nil,
	[]byte{},
	"",
	[]byte("a"),
	"0",
	"0.0000_0001",
	[]byte("14687233442.06916608"),
	"14_687_233_442.069_166_08",
	nilRat,
	NewRat("14687233442.06916608"),
	*NewRat("14687233442.06916608"),
	stdNilRat,
	stdRat,
	big.NewRat(14687233442, 100_000_000),
	*big.NewRat(14687233442, 100_000_000),
	uint16(math.MaxUint16),
	uint32(math.MaxUint32),
	uint64(math.MaxUint64),
	stdNilInt,
	big.NewInt(100_000_000),
}

for _, v := range inputs {
	fmt.Println(NewRat(v))
}
Output:

0
0
0
0
0
0.00000001
14687233442.06916608
14687233442.06916608
0
14687233442.06916608
14687233442.06916608
0
0
146.87233442
146.87233442
65535
4294967295
18446744073709551615
0
100000000

func QuoRat

func QuoRat(f ...interface{}) *Rat

QuoRat return the quotient of `f[0]/f[1]/...` as new Rat. It will return nil if the first parameter is not convertable to Rat. If the second or rest of parameters can not be converted to Rat or zero it will return nil instead of panic.

Example
fmt.Println(QuoRat())
fmt.Println(QuoRat(nil))
fmt.Println(QuoRat("a"))
fmt.Println(QuoRat("0"))
fmt.Println(QuoRat(2, 0, 2))
fmt.Println(QuoRat(6, "a", "0.3"))
fmt.Println(QuoRat(0, 1))
fmt.Println(QuoRat(4651, 272))
fmt.Println(QuoRat(int64(1815507979407), NewRat(100000000)))
fmt.Println(QuoRat("25494300", "25394000000"))
Output:

0
0
0
0
0
0
0
17.0992647
18155.07979407
0.00100395

func SubRat

func SubRat(f ...interface{}) *Rat

SubRat return the result of subtraction `f[0]-f[1]-...` as new Rat. It will return nil if the first parameter is not convertable to Rat.

Example
fmt.Println(SubRat())
fmt.Println(SubRat(nil))
fmt.Println(SubRat("a"))
fmt.Println(SubRat(0, 1))
fmt.Println(SubRat(6, "a", "0.3"))
Output:

0
0
0
-1
5.7

func (*Rat) Abs

func (r *Rat) Abs() *Rat

Abs sets r to |r| (the absolute value of r) and return it.

Example
fmt.Println(NewRat(nil).Abs())
fmt.Println(NewRat("-1").Abs())
fmt.Println(NewRat("-0.00001").Abs())
fmt.Println(NewRat("1").Abs())
Output:

0
1
0.00001
1

func (*Rat) Add

func (r *Rat) Add(g interface{}) *Rat

Add sets r to `r+g` and return the r as the result. If g is not convertable to Rat it will equal to r+0.

Example
fmt.Println(NewRat(nil).Add(nil))
fmt.Println(NewRat(1).Add(nil))
fmt.Println(NewRat(1).Add(1))
Output:

0
1
2

func (*Rat) Humanize

func (r *Rat) Humanize(thousandSep, decimalSep string) string

Humanize format the r into string with custom thousand and decimal separator.

Example
var (
	thousandSep = "."
	decimalSep  = ","
)
fmt.Printf("%s\n", NewRat(nil).Humanize(thousandSep, decimalSep))
fmt.Printf("%s\n", NewRat("0").Humanize(thousandSep, decimalSep))
fmt.Printf("%s\n", NewRat("0.1234").Humanize(thousandSep, decimalSep))
fmt.Printf("%s\n", NewRat("100").Humanize(thousandSep, decimalSep))
fmt.Printf("%s\n", NewRat("100.1234").Humanize(thousandSep, decimalSep))
fmt.Printf("%s\n", NewRat("1000").Humanize(thousandSep, decimalSep))
fmt.Printf("%s\n", NewRat("1000.2").Humanize(thousandSep, decimalSep))
fmt.Printf("%s\n", NewRat("10000.23").Humanize(thousandSep, decimalSep))
fmt.Printf("%s\n", NewRat("100000.234").Humanize(thousandSep, decimalSep))
Output:

0
0
0,1234
100
100,1234
1.000
1.000,2
10.000,23
100.000,234

func (*Rat) Int64

func (r *Rat) Int64() int64

Int64 return the integer resulting from truncating r towards zero. It will return math.MaxInt64, if the value is larger than MaxInt64. It will return math.MinInt64, if the value is lower than MinInt64.

Example
fmt.Printf("MaxInt64: %d\n", NewRat("9223372036854775807").Int64())
fmt.Printf("MaxInt64+1: %d\n", NewRat("9223372036854775808").Int64())
fmt.Printf("MinInt64: %d\n", NewRat("-9223372036854775808").Int64())
fmt.Printf("MinInt64-1: %d\n", NewRat("-9223372036854775809").Int64())

fmt.Println(NewRat(nil).Int64())
fmt.Println(NewRat("0.000_000_001").Int64())
fmt.Println(NewRat("0.5").Int64())
fmt.Println(NewRat("0.6").Int64())
fmt.Println(NewRat("4011144900.02438879").Mul(100000000).Int64())
fmt.Println(QuoRat("128_900", "0.000_0322").Int64())
fmt.Println(QuoRat(128900, 3220).Mul(100000000).Int64())
fmt.Println(QuoRat(25494300, QuoRat(25394000000, 100000000)).Int64())
Output:

MaxInt64: 9223372036854775807
MaxInt64+1: 9223372036854775807
MinInt64: -9223372036854775808
MinInt64-1: -9223372036854775808
0
0
0
0
401114490002438879
4003105590
4003105590
100394

func (*Rat) IsEqual

func (r *Rat) IsEqual(g interface{}) bool

IsEqual will return true if `r == g`, including when r and g are both nil.

Unlike the standard Cmp(), if the first call to Cmp is not 0, it will try to compare the string values of r and g, truncated by DefaultDigitPrecision.

Example
f := NewRat(1)

fmt.Println(NewRat(nil).IsEqual(0))
fmt.Println(f.IsEqual("a"))
fmt.Println(f.IsEqual("1"))
fmt.Println(f.IsEqual(1.1))
fmt.Println(f.IsEqual(byte(1)))
fmt.Println(f.IsEqual(int(1)))
fmt.Println(f.IsEqual(int32(1)))
fmt.Println(f.IsEqual(float32(1)))
fmt.Println(f.IsEqual(NewRat(1)))
// Equal due to String() truncation to DefaultDigitPrecision (8) digits.
fmt.Println(NewRat("0.1234567890123").IsEqual("0.12345678"))
Output:

false
false
true
false
true
true
true
true
true
true

func (*Rat) IsGreater

func (r *Rat) IsGreater(g interface{}) bool

IsGreater will return true if `r > g`. If g is not convertable to Rat it will return false.

Example
r := NewRat("0.000_000_5")

fmt.Println(NewRat(nil).IsGreater(0))
fmt.Println(r.IsGreater(nil))
fmt.Println(r.IsGreater("0.000_000_5"))
fmt.Println(r.IsGreater("0.000_000_49999"))
Output:

false
false
false
true

func (*Rat) IsGreaterOrEqual

func (r *Rat) IsGreaterOrEqual(g interface{}) bool

IsGreaterOrEqual will return true if `r >= g`. If g is not convertable to Rat it will return false.

Example
r := NewRat("0.000_000_5")

fmt.Println(NewRat(nil).IsGreaterOrEqual(0))
fmt.Println(r.IsGreaterOrEqual(nil))
fmt.Println(r.IsGreaterOrEqual("0.000_000_500_000_000_001"))
fmt.Println(r.IsGreaterOrEqual("0.000_000_5"))
fmt.Println(r.IsGreaterOrEqual("0.000_000_49999"))
Output:

false
false
false
true
true

func (*Rat) IsGreaterThanZero

func (r *Rat) IsGreaterThanZero() bool

IsGreaterThanZero will return true if `r > 0`.

Example
fmt.Println(NewRat(nil).IsGreaterThanZero())
fmt.Println(NewRat(0).IsGreaterThanZero())
fmt.Println(NewRat("-0.000_000_000_000_000_001").IsGreaterThanZero())
fmt.Println(NewRat("0.000_000_000_000_000_001").IsGreaterThanZero())
Output:

false
false
false
true

func (*Rat) IsLess

func (r *Rat) IsLess(g interface{}) bool

IsLess will return true if `r < g`. If r is nill or g is not convertable to Rat it will return false.

Example
r := NewRat("0.000_000_5")

fmt.Println(NewRat(nil).IsLess(0))
fmt.Println(r.IsLess(nil))
fmt.Println(r.IsLess("0.000_000_5"))
fmt.Println(r.IsLess("0.000_000_49"))
fmt.Println(r.IsLess("0.000_000_500_000_000_001"))
Output:

false
false
false
false
true

func (*Rat) IsLessOrEqual

func (r *Rat) IsLessOrEqual(g interface{}) bool

IsLessOrEqual will return true if `r <= g`. It r is nil or g is not convertable to Rat it will return false.

Example
r := NewRat("0.000_000_5")

fmt.Println(NewRat(nil).IsLessOrEqual(r))
fmt.Println(r.IsLessOrEqual(nil))
fmt.Println(r.IsLessOrEqual("0.000_000_5"))
fmt.Println(r.IsLessOrEqual("0.000_000_49"))
fmt.Println(r.IsLessOrEqual("0.000_000_500_000_000_001"))
Output:

false
false
true
false
true

func (*Rat) IsLessThanZero

func (r *Rat) IsLessThanZero() bool

IsLessThanZero return true if `r < 0`.

Example
fmt.Println(NewRat(nil).IsLessThanZero())
fmt.Println(NewRat(byte(0)).IsLessThanZero())
fmt.Println(NewRat("-0.000_000_000_000_000_001").IsLessThanZero())
fmt.Println(NewRat("0.000_000_000_000_000_001").IsLessThanZero())
Output:

false
false
true
false

func (*Rat) IsZero

func (r *Rat) IsZero() bool

IsZero will return true if `r == 0`.

Example
fmt.Println(NewRat(nil).IsZero())
fmt.Println(NewRat(byte(0)).IsZero())
fmt.Println(NewRat(byte(-0)).IsZero())
fmt.Println(NewRat("-0.000_000_000_000_000_001").IsZero())
fmt.Println(NewRat("0.000_000_000_000_000_001").IsZero())
Output:

false
true
true
false
false

func (*Rat) MarshalJSON

func (r *Rat) MarshalJSON() ([]byte, error)

MarshalJSON implement the json.Marshaler interface. It will return the same result as String().

Example
inputs := []string{
	"",
	"a",
	"0.0000_0000",
	"0.1",
	"0.0000_0001",
	"0.0000_0000_1", // Truncated by DefaultDigitPrecision.
	"1234567890.0",
	"64.23738872403", // Truncated by DefaultDigitPrecision.
	"0.1234567890",
	"142660378.65368736",
	"9193394308.85771370",
	"14687233442.06916608",
}

MarshalJSONAsString = true
for _, in := range inputs {
	out, _ := NewRat(in).MarshalJSON()
	fmt.Printf("%s\n", out)
}

// Setting this to false will make the JSON output become number.
MarshalJSONAsString = false

for _, in := range inputs {
	out, _ := NewRat(in).MarshalJSON()
	fmt.Printf("%s\n", out)
}
Output:

"0"
"0"
"0"
"0.1"
"0.00000001"
"0"
"1234567890"
"64.23738872"
"0.12345678"
"142660378.65368736"
"9193394308.8577137"
"14687233442.06916608"
0
0
0
0.1
0.00000001
0
1234567890
64.23738872
0.12345678
142660378.65368736
9193394308.8577137
14687233442.06916608
Example (WithStruct)
type T struct {
	V *Rat `json:"V"`
}

inputs := []T{
	{V: nil},
	{V: NewRat(0)},
	{V: NewRat("0.1234567890")},
}

var (
	in  T
	err error
	out []byte
)
MarshalJSONAsString = true
for _, in = range inputs {
	out, err = json.Marshal(&in)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", out)
}

MarshalJSONAsString = false
for _, in = range inputs {
	out, err = json.Marshal(&in)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", out)
}
Output:

{"V":null}
{"V":"0"}
{"V":"0.12345678"}
{"V":null}
{"V":0}
{"V":0.12345678}

func (*Rat) Mul

func (r *Rat) Mul(g interface{}) *Rat

Mul sets r to product of `r * g` and return the result as r. If g is not convertible to Rat it will return nil.

Example
const (
	defValue = "14687233442.06916608"
)

fmt.Println(NewRat(defValue).Mul("a"))
fmt.Println(NewRat(defValue).Mul("0"))
fmt.Println(NewRat(defValue).Mul(defValue))
fmt.Println(NewRat("1.06916608").Mul("1.06916608"))
Output:

0
0
215714826181834884090.46087866
1.1431161

func (*Rat) Quo

func (r *Rat) Quo(g interface{}) *Rat

Quo sets r to quotient of `r/g` and return the result as r. If r is nil or g is not convertible to Rat or zero it will return nil.

Example
const (
	defValue = "14687233442.06916608"
)

fmt.Println(NewRat(nil).Quo(1))
fmt.Println(NewRat(defValue).Quo(nil))
fmt.Println(NewRat(defValue).Quo("a"))
fmt.Println(NewRat(defValue).Quo("100_000_000"))
Output:

0
0
0
146.87233442

func (*Rat) RoundNearestFraction

func (r *Rat) RoundNearestFraction() *Rat

RoundNearestFraction round the fraction to the nearest non-zero value.

The RoundNearestFraction does not require precision parameter, like in other rounds function, but it will figure it out based on the last non-zero value from fraction.

See example for more information.

Example
fmt.Printf("nil: %s\n", NewRat(nil).RoundNearestFraction())
fmt.Printf("0.000000001: %s\n", NewRat("0").RoundNearestFraction()) // Affected by DefaultDigitPrecision (8)
fmt.Printf("0.00545: %s\n", NewRat("0.00545").RoundNearestFraction())
fmt.Printf("0.00555: %s\n", NewRat("0.00555").RoundNearestFraction())
fmt.Printf("0.0545: %s\n", NewRat("0.0545").RoundNearestFraction())
fmt.Printf("0.0555: %s\n", NewRat("0.0555").RoundNearestFraction())
fmt.Printf("0.545: %s\n", NewRat("0.545").RoundNearestFraction())
fmt.Printf("0.555: %s\n", NewRat("0.555").RoundNearestFraction())
fmt.Printf("0.5: %s\n", NewRat("0.5").RoundNearestFraction())
fmt.Printf("-0.5: %s\n", NewRat("-0.5").RoundNearestFraction())
fmt.Printf("-0.555: %s\n", NewRat("-0.555").RoundNearestFraction())
fmt.Printf("-0.545: %s\n", NewRat("-0.545").RoundNearestFraction())
Output:

nil: 0
0.000000001: 0
0.00545: 0.005
0.00555: 0.006
0.0545: 0.05
0.0555: 0.06
0.545: 0.5
0.555: 0.6
0.5: 0.5
-0.5: -0.5
-0.555: -0.6
-0.545: -0.5

func (*Rat) RoundToNearestAway

func (r *Rat) RoundToNearestAway(prec int) *Rat

RoundToNearestAway round r to n digit precision using nearest away mode, where mantissa is accumulated by the last digit after precision. For example, using 2 digit precision, 0.555 would become 0.56.

Example
fmt.Printf("nil: %s\n", NewRat(nil).RoundToNearestAway(2))
fmt.Printf("0.0054: %s\n", NewRat("0.0054").RoundToNearestAway(2))
fmt.Printf("0.0054: %s\n", NewRat("0.0054").RoundToNearestAway(1))
fmt.Printf("0.5455: %s\n", NewRat("0.5455").RoundToNearestAway(2))
fmt.Printf("0.5555: %s\n", NewRat("0.5555").RoundToNearestAway(2))
fmt.Printf("0.5566: %s\n", NewRat("0.5567").RoundToNearestAway(2))
fmt.Printf("0.5566: %s\n", NewRat("0.5566").RoundToNearestAway(0))

fmt.Printf("0.02514135: %s\n", NewRat("0.02514135").RoundToNearestAway(6))
fmt.Printf("0.02514145: %s\n", NewRat("0.02514145").RoundToNearestAway(6))
fmt.Printf("0.02514155: %s\n", NewRat("0.02514155").RoundToNearestAway(6))
fmt.Printf("0.02514165: %s\n", NewRat("0.02514165").RoundToNearestAway(6))

fmt.Printf("0.5: %s\n", NewRat("0.5").RoundToNearestAway(0))
fmt.Printf("-0.5: %s\n", NewRat("-0.5").RoundToNearestAway(0))
Output:

nil: 0
0.0054: 0.01
0.0054: 0
0.5455: 0.55
0.5555: 0.56
0.5566: 0.56
0.5566: 1
0.02514135: 0.025141
0.02514145: 0.025141
0.02514155: 0.025142
0.02514165: 0.025142
0.5: 1
-0.5: -1

func (*Rat) RoundToZero

func (r *Rat) RoundToZero(prec int) *Rat

RoundToZero round r to n digit precision using to zero mode. For example, using 2 digit precision, 0.555 would become 0.55.

Example
fmt.Println(NewRat(nil).RoundToZero(2))
fmt.Println(NewRat("0.5455").RoundToZero(2))
fmt.Println(NewRat("0.5555").RoundToZero(2))
fmt.Println(NewRat("0.5566").RoundToZero(2))
fmt.Println(NewRat("0.5566").RoundToZero(0))
// In Go <= 1.18, this will print "-0", but on Go tip "0".
// So to make test success on all versions, we multiple it to 1.
fmt.Println(NewRat("-0.5").RoundToZero(0).Mul(1))
Output:

0
0.54
0.55
0.55
0
0

func (*Rat) Scan

func (r *Rat) Scan(v interface{}) error

Scan implement the database's sql.Scan interface.

Example
var (
	r   = &Rat{}
	err error
)

inputs := []interface{}{
	1234,
	nil,
	"0.0001",
	float64(0.0001),
}
for _, in := range inputs {
	err = r.Scan(in)
	if err != nil {
		fmt.Printf("error: %s\n", err)
	}
	fmt.Println(r)
}
Output:

1234
error: Rat.Scan: unknown type <nil>
1234
0.0001
0.0001

func (*Rat) String

func (r *Rat) String() string

String format the Rat value into string with maximum mantissa is set by digit precision option with rounding mode set to zero.

Unlike standard String method, this method will trim trailing zero digit or decimal point at the end of mantissa.

Example
inputs := []interface{}{
	nil,
	"12345",
	"0.00000000",
	float64(0.00000000),
	"0.1",
	float64(0.1),
	"0.0000001",
	float64(0.0000001),
	"0.000000001", // Truncated due to rounding.
	"64.23738872403",
	float64(64.23738872403),
}
for _, in := range inputs {
	fmt.Println(NewRat(in).String())
}
Output:

0
12345
0
0
0.1
0.1
0.0000001
0.0000001
0
64.23738872
64.23738872

func (*Rat) Sub

func (r *Rat) Sub(g interface{}) *Rat

Sub sets r to rounded difference `r-g` and return r. If g is not convertable to Rat, it will return as r-0.

Example
fmt.Println(NewRat(nil).Sub(1))
fmt.Println(NewRat(1).Sub(nil))
fmt.Println(NewRat(1).Sub(1))
Output:

0
1
0

func (*Rat) UnmarshalJSON

func (r *Rat) UnmarshalJSON(in []byte) (err error)

UnmarshalJSON convert the JSON byte value into Rat.

Example (WithStruct)
type T struct {
	V *Rat `json:"V"`
	W *Rat `json:"W,omitempty"`
}

inputs := []string{
	`{"V":"ab"}`,
	`{}`,
	`{"V":}`,
	`{"V":0,"W":0}`,
	`{"V":"1"}`,
	`{"V":0.123456789}`,
	`{"V":"0.1234", "W":0.5678}`,
}
for _, in := range inputs {
	t := T{}
	err := json.Unmarshal([]byte(in), &t)
	if err != nil {
		fmt.Println(err)
		continue
	}
	fmt.Printf("%s %s\n", t.V, t.W)
}
Output:

Rat.UnmarshalJSON: cannot convert []uint8([97 98]) to Rat
0 0
invalid character '}' looking for beginning of value
0 0
1 0
0.12345678 0
0.1234 0.5678

func (*Rat) Value

func (r *Rat) Value() (driver.Value, error)

Value return the []byte value for database/sql, as defined in sql/driver.Valuer. It will return "0" if r is nil.

Example
inputs := []interface{}{
	nil,
	0,
	1.2345,
	"12345.6789_1234_5678_9",
}
for _, in := range inputs {
	out, _ := NewRat(in).Value()
	fmt.Printf("%s\n", out)
}
Output:

0
0
1.2345
12345.67891234

Jump to

Keyboard shortcuts

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