Documentation ¶
Overview ¶
Package decimal implements immutable decimal floating-point numbers. It is specifically designed for transactional financial systems and adheres to the principles set by ANSI X3.274-1996.
Internal Representation ¶
Decimal is a struct with three fields:
- Sign: A boolean indicating whether the decimal is negative.
- Coefficient: An unsigned integer representing the numeric value of the decimal without the decimal point.
- Scale: A non-negative integer indicating the position of the decimal point within the coefficient. For example, a decimal with a coefficient of 12345 and a scale of 2 represents the value 123.45. Conceptually, the scale can be understood as the inverse of the exponent in scientific notation. For example, a scale of 2 corresponds to an exponent of -2. The range of allowed values for the scale is from 0 to 19.
The numerical value of a decimal is calculated as follows:
- -Coefficient / 10^Scale if Sign is true.
- Coefficient / 10^Scale if Sign is false.
This approach allows the same numeric value to have multiple representations, for example, 1, 1.0, and 1.00, which represent the same value but have different scales and coefficients.
Constraints Overview ¶
The range of a decimal is determined by its scale. Here are the ranges for frequently used scales:
| Example | Scale | Minimum | Maximum | | ------------ | ----- | ------------------------------------ | ----------------------------------- | | Japanese Yen | 0 | -9,999,999,999,999,999,999 | 9,999,999,999,999,999,999 | | US Dollar | 2 | -99,999,999,999,999,999.99 | 99,999,999,999,999,999.99 | | Omani Rial | 3 | -9,999,999,999,999,999.999 | 9,999,999,999,999,999.999 | | Bitcoin | 8 | -99,999,999,999.99999999 | 99,999,999,999.99999999 | | Ethereum | 9 | -9,999,999,999.999999999 | 9,999,999,999.999999999 |
Subnormal numbers are not supported to ensure peak performance. Consequently, decimals between -0.00000000000000000005 and 0.00000000000000000005 inclusive, are rounded to 0.
Special values such as NaN, Infinity, or negative zeros are not supported. This ensures that arithmetic operations always produce either valid decimals or errors.
Arithmetic Operations ¶
Each arithmetic operation occurs in two steps:
The operation is initially performed using uint64 arithmetic. If no overflow occurs, the exact result is immediately returned. If overflow occurs, the operation proceeds to step 2.
The operation is repeated with at least double precision using big.Int arithmetic. The result is then rounded to 19 digits. If no significant digits are lost during rounding, the inexact result is returned. If any significant digit is lost, an overflow error is returned.
Step 1 improves performance by avoiding the performance impact associated with big.Int arithmetic. It is expected that, in transactional financial systems, most arithmetic operations will compute an exact result during step 1.
The following rules determine the significance of digits during step 2:
- For Decimal.Add, Decimal.Sub, Decimal.Mul, Decimal.Quo, Decimal.QuoRem, Decimal.Inv, Decimal.AddMul, Decimal.AddQuo, Decimal.SubMul, Decimal.SubQuo, Decimal.SubAbs, Decimal.PowInt, Sum, Mean, Prod: All digits in the integer part are significant, while digits in the fractional part are considered insignificant.
- For Decimal.AddExact, Decimal.SubExact, Decimal.MulExact, Decimal.QuoExact, Decimal.AddMulExact, Decimal.AddQuoExact, Decimal.SubMulExact, Decimal.SubQuoExact: All digits in the integer part are significant. The significance of digits in the fractional part is determined by the scale argument, which is typically equal to the scale of the currency.
Transcendental Functions ¶
All transcendental functions are always computed with at least double precision using big.Int arithmetic. The result is then rounded to 19 digits. If no significant digits are lost during rounding, the inexact result is returned. If any significant digit is lost, an overflow error is returned.
The following rules determine the significance of digits:
- For Decimal.Sqrt, Decimal.Exp, Decimal.Log, Decimal.Log2, Decimal.Log10, Decimal.Pow: All digits in the integer part are significant, while digits in the fractional part are considered insignificant.
Mathematical Context ¶
Unlike many other decimal libraries, this package does not provide an explicit mathematical context. Instead, the context is implicit and can be approximately equated to the following settings:
| Attribute | Value | | ----------------------- | ----------------------------------------------- | | Precision | 19 | | Maximum Exponent (Emax) | 18 | | Minimum Exponent (Emin) | -19 | | Tiny Exponent (Etiny) | -19 | | Rounding Method | Half To Even | | Enabled Traps | Division by Zero, Invalid Operation, Overflow | | Disabled Traps | Inexact, Clamped, Rounded, Subnormal, Underflow |
The equality of Etiny and Emin implies that this package does not support subnormal numbers.
Rounding Methods ¶
For all operations, the result is the one that would be obtained by computing the exact result with infinite precision and then rounding it to 19 digits using half-to-even rounding. This method ensures that the result is as close as possible to the true mathematical value and that rounding errors are evenly distributed between rounding up and down.
In addition to implicit rounding, the package provides several methods for explicit rounding:
- Half-to-even rounding: Decimal.Round, Decimal.Quantize, Decimal.Rescale.
- Rounding towards positive infinity: Decimal.Ceil.
- Rounding towards negative infinity: Decimal.Floor.
- Rounding towards zero: Decimal.Trunc.
See the documentation for each method for more details.
Error Handling ¶
All methods are panic-free and pure. Errors are returned in the following cases:
Division by Zero: Unlike Go's standard library, Decimal.Quo, Decimal.QuoRem, Decimal.Inv, Decimal.AddQuo, Decimal.SubQuo, do not panic when dividing by 0. Instead, they return an error.
Invalid Operation: Sum, Mean and Prod return an error if no arguments are provided. Decimal.PowInt returns an error if 0 is raised to a negative power. Decimal.Sqrt returns an error if the square root of a negative decimal is requested. Decimal.Log, Decimal.Log2, Decimal.Log10 return an error when calculating a logarithm of a non-positive decimal. Decimal.Pow returns an error if 0 is raised to a negative powere or a negative decimal is raised to a fractional power.
Overflow: Unlike standard integers, decimals do not "wrap around" when exceeding their maximum value. For out-of-range values, methods return an error.
Errors are not returned in the following cases:
- Underflow: Methods do not return an error for decimal underflow. If the result is a decimal between -0.00000000000000000005 and 0.00000000000000000005 inclusive, it will be rounded to 0.
Data Conversion ¶
A. JSON
The package integrates with standard encoding/json through the implementation of encoding.TextMarshaller and encoding.TextUnmarshaler interfaces. Below is an example structure:
type Object struct { Number decimal.Decimal `json:"some_number"` // Other fields... }
This package marshals decimals as quoted strings, ensuring the preservation of the exact numerical value. Below is an example OpenAPI schema:
Decimal: type: string format: decimal pattern: '^(\-|\+)?((\d+(\.\d*)?)|(\.\d+))$'
B. BSON
The package integrates with mongo-driver/v2/bson via the implementation of bson.ValueMarshaler and bson.ValueUnmarshaler interfaces. This package marshals decimals as Decimal128, ensuring the preservation of the exact numerical value.
C. XML
The package integrates with standard encoding/xml via the implementation of encoding.TextMarshaller and encoding.TextUnmarshaler interfaces. Below is an example structure:
type Entity struct { Number decimal.Decimal `xml:"SomeNumber"` // Other fields... }
"xs:decimal" type can represent decimals in XML schema. It is possible to impose restrictions on the length of the decimals using the following type:
<xs:simpleType name="Decimal"> <xs:restriction base="xs:decimal"> <xs:totalDigits value="19"/> </xs:restriction> </xs:simpleType>
D. Protocol Buffers
Protocol Buffers provide two formats to represent decimals. The first format represents decimals as numerical strings. The main advantage of this format is that it preserves trailing zeros. To convert between this format and decimals, use Parse and Decimal.String. Below is an example of a proto definition:
message Decimal { string value = 1; }
The second format represents decimals as a pair of integers: one for the integer part and another for the fractional part. This format does not preserve trailing zeros and rounds decimals with more than nine digits in the fractional part. For conversion between this format and decimals, use NewFromInt64 and Decimal.Int64 with a scale argument of "9". Below is an example of a proto definition:
message Decimal { int64 units = 1; int32 nanos = 2; }
E. SQL
The package integrates with the standard database/sql via the implementation of sql.Scanner and driver.Valuer interfaces. To ensure accurate preservation of decimal scales, it is essential to choose appropriate column types:
| Database | Type | | ---------- | ----------------------------- | | PostgreSQL | DECIMAL | | SQLite | TEXT | | MySQL | DECIMAL(19, d) or VARCHAR(22) |
Below are the reasons for these preferences:
PostgreSQL: Always use DECIMAL without precision or scale specifications, that is, avoid DECIMAL(p) or DECIMAL(p, s). DECIMAL accurately preserves the scale of decimals.
SQLite: Prefer TEXT, since DECIMAL is just an alias for binary floating-point numbers. TEXT accurately preserves the scale of decimals.
MySQL: Use DECIMAL(19, d), as DECIMAL is merely an alias for DECIMAL(10, 0). The downside of this format is that MySQL automatically rescales all decimals: it rounds values with more than d digits in the fractional part (using half away from zero) and pads with trailing zeros those with fewer than d digits in the fractional part. To prevent automatic rescaling, consider using VARCHAR(22), which accurately preserves the scale of decimals.
Example (FloatInaccuracy) ¶
This example demonstrates the advantage of decimals for financial calculations. It computes the sum 0.1 + 0.2 using both decimal and float64 arithmetic. In decimal arithmetic, the result is exactly 0.3, as expected. In float64 arithmetic, the result is 0.30000000000000004 due to floating-point inaccuracy.
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { a := decimal.MustParse("0.1") b := decimal.MustParse("0.2") fmt.Println(a.Add(b)) x := 0.1 y := 0.2 fmt.Println(x + y) }
Output: 0.3 <nil> 0.30000000000000004
Example (PiApproximation) ¶
This example calculates an approximate value of π using the Leibniz formula. The Leibniz formula is an infinite series that converges to π/4, and is given by the equation: 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + ... = π/4. This example computes the series up to the 500,000th term using decimal arithmetic and returns the approximate value of π.
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { fmt.Println(approximate(500_000)) fmt.Println(decimal.Pi) } func approximate(terms int) (decimal.Decimal, error) { pi := decimal.Zero denominator := decimal.One increment := decimal.Two multiplier := decimal.MustParse("4") var err error for range terms { pi, err = pi.AddQuo(multiplier, denominator) if err != nil { return decimal.Decimal{}, err } denominator, err = denominator.Add(increment) if err != nil { return decimal.Decimal{}, err } multiplier = multiplier.Neg() } return pi, nil }
Output: 3.141590653589793192 <nil> 3.141592653589793238
Example (PostfixCalculator) ¶
This example implements a simple calculator that evaluates mathematical expressions written in postfix notation. The calculator can handle basic arithmetic operations such as addition, subtraction, multiplication, and division.
package main import ( "fmt" "strings" "github.com/govalues/decimal" ) func main() { fmt.Println(evaluate("1.23 4.56 + 10 *")) } func evaluate(input string) (decimal.Decimal, error) { tokens := strings.Fields(input) if len(tokens) == 0 { return decimal.Decimal{}, fmt.Errorf("no tokens") } stack := make([]decimal.Decimal, 0, len(tokens)) for i, token := range tokens { var err error var result decimal.Decimal if token == "+" || token == "-" || token == "*" || token == "/" { if len(stack) < 2 { return decimal.Decimal{}, fmt.Errorf("not enough operands") } left := stack[len(stack)-2] right := stack[len(stack)-1] stack = stack[:len(stack)-2] switch token { case "+": result, err = left.Add(right) case "-": result, err = left.Sub(right) case "*": result, err = left.Mul(right) case "/": result, err = left.Quo(right) } } else { result, err = decimal.Parse(token) } if err != nil { return decimal.Decimal{}, fmt.Errorf("processing token %q at position %v: %w", token, i, err) } stack = append(stack, result) } if len(stack) != 1 { return decimal.Decimal{}, fmt.Errorf("stack contains %v, expected exactly one item", stack) } return stack[0], nil }
Output: 57.90 <nil>
Index ¶
- Constants
- Variables
- type Decimal
- func Mean(d ...Decimal) (Decimal, error)
- func MustNew(value int64, scale int) Decimal
- func MustParse(s string) Decimal
- func New(value int64, scale int) (Decimal, error)
- func NewFromFloat64(f float64) (Decimal, error)
- func NewFromInt64(whole, frac int64, scale int) (Decimal, error)
- func Parse(s string) (Decimal, error)
- func ParseExact(s string, scale int) (Decimal, error)
- func Prod(d ...Decimal) (Decimal, error)
- func Sum(d ...Decimal) (Decimal, error)
- func (d Decimal) Abs() Decimal
- func (d Decimal) Add(e Decimal) (Decimal, error)
- func (d Decimal) AddExact(e Decimal, scale int) (Decimal, error)
- func (d Decimal) AddMul(e, f Decimal) (Decimal, error)
- func (d Decimal) AddMulExact(e, f Decimal, scale int) (Decimal, error)
- func (d Decimal) AddQuo(e, f Decimal) (Decimal, error)
- func (d Decimal) AddQuoExact(e, f Decimal, scale int) (Decimal, error)
- func (d Decimal) Ceil(scale int) Decimal
- func (d Decimal) Clamp(min, max Decimal) (Decimal, error)
- func (d Decimal) Cmp(e Decimal) int
- func (d Decimal) CmpAbs(e Decimal) int
- func (d Decimal) CmpTotal(e Decimal) int
- func (d Decimal) Coef() uint64
- func (d Decimal) CopySign(e Decimal) Decimal
- func (d Decimal) Equal(e Decimal) bool
- func (d Decimal) Exp() (Decimal, error)
- func (d Decimal) Float64() (f float64, ok bool)
- func (d Decimal) Floor(scale int) Decimal
- func (d Decimal) Format(state fmt.State, verb rune)
- func (d Decimal) Int64(scale int) (whole, frac int64, ok bool)
- func (d Decimal) Inv() (Decimal, error)
- func (d Decimal) IsInt() bool
- func (d Decimal) IsNeg() bool
- func (d Decimal) IsOne() bool
- func (d Decimal) IsPos() bool
- func (d Decimal) IsZero() bool
- func (d Decimal) Less(e Decimal) bool
- func (d Decimal) Log() (Decimal, error)
- func (d Decimal) Log10() (Decimal, error)
- func (d Decimal) Log2() (Decimal, error)
- func (d Decimal) MarshalBSONValue() (typ byte, data []byte, err error)
- func (d Decimal) MarshalBinary() ([]byte, error)
- func (d Decimal) MarshalJSON() ([]byte, error)
- func (d Decimal) MarshalText() ([]byte, error)
- func (d Decimal) Max(e Decimal) Decimal
- func (d Decimal) Min(e Decimal) Decimal
- func (d Decimal) MinScale() int
- func (d Decimal) Mul(e Decimal) (Decimal, error)
- func (d Decimal) MulExact(e Decimal, scale int) (Decimal, error)
- func (d Decimal) Neg() Decimal
- func (d Decimal) One() Decimal
- func (d Decimal) Pad(scale int) Decimal
- func (d Decimal) Pow(e Decimal) (Decimal, error)
- func (d Decimal) PowInt(power int) (Decimal, error)
- func (d Decimal) Prec() int
- func (d Decimal) Quantize(e Decimal) Decimal
- func (d Decimal) Quo(e Decimal) (Decimal, error)
- func (d Decimal) QuoExact(e Decimal, scale int) (Decimal, error)
- func (d Decimal) QuoRem(e Decimal) (q, r Decimal, err error)
- func (d Decimal) Rescale(scale int) Decimal
- func (d Decimal) Round(scale int) Decimal
- func (d Decimal) SameScale(e Decimal) bool
- func (d Decimal) Scale() int
- func (d *Decimal) Scan(value any) error
- func (d Decimal) Sign() int
- func (d Decimal) Sqrt() (Decimal, error)
- func (d Decimal) String() string
- func (d Decimal) Sub(e Decimal) (Decimal, error)
- func (d Decimal) SubAbs(e Decimal) (Decimal, error)
- func (d Decimal) SubExact(e Decimal, scale int) (Decimal, error)
- func (d Decimal) SubMul(e, f Decimal) (Decimal, error)
- func (d Decimal) SubMulExact(e, f Decimal, scale int) (Decimal, error)
- func (d Decimal) SubQuo(e, f Decimal) (Decimal, error)
- func (d Decimal) SubQuoExact(e, f Decimal, scale int) (Decimal, error)
- func (d Decimal) Trim(scale int) Decimal
- func (d Decimal) Trunc(scale int) Decimal
- func (d Decimal) ULP() Decimal
- func (d *Decimal) UnmarshalBSONValue(typ byte, data []byte) error
- func (d *Decimal) UnmarshalBinary(data []byte) error
- func (d *Decimal) UnmarshalJSON(data []byte) error
- func (d *Decimal) UnmarshalText(text []byte) error
- func (d Decimal) Value() (driver.Value, error)
- func (d Decimal) WithinOne() bool
- func (d Decimal) Zero() Decimal
- type NullDecimal
- func (n NullDecimal) MarshalBSONValue() (typ byte, data []byte, err error)
- func (n NullDecimal) MarshalJSON() ([]byte, error)
- func (n *NullDecimal) Scan(value any) error
- func (n *NullDecimal) UnmarshalBSONValue(typ byte, data []byte) error
- func (n *NullDecimal) UnmarshalJSON(data []byte) error
- func (n NullDecimal) Value() (driver.Value, error)
Examples ¶
- Package (FloatInaccuracy)
- Package (PiApproximation)
- Package (PostfixCalculator)
- Decimal.Abs
- Decimal.Add
- Decimal.AddExact
- Decimal.AddMul
- Decimal.AddMulExact
- Decimal.AddQuo
- Decimal.AddQuoExact
- Decimal.Ceil
- Decimal.Clamp
- Decimal.Cmp
- Decimal.Cmp (Slices)
- Decimal.CmpAbs
- Decimal.CmpAbs (Slices)
- Decimal.CmpTotal
- Decimal.CmpTotal (Slices)
- Decimal.Coef
- Decimal.CopySign
- Decimal.Equal
- Decimal.Equal (Slices)
- Decimal.Exp
- Decimal.Float64
- Decimal.Floor
- Decimal.Format
- Decimal.Int64
- Decimal.Inv
- Decimal.IsInt
- Decimal.IsInt (Slices)
- Decimal.IsNeg
- Decimal.IsNeg (Slices)
- Decimal.IsOne
- Decimal.IsOne (Slices)
- Decimal.IsPos
- Decimal.IsPos (Slices)
- Decimal.IsZero
- Decimal.IsZero (Slices)
- Decimal.Less
- Decimal.Log
- Decimal.Log10
- Decimal.Log2
- Decimal.MarshalBSONValue (Bson)
- Decimal.MarshalBinary (Gob)
- Decimal.MarshalJSON (Json)
- Decimal.MarshalText (Xml)
- Decimal.Max
- Decimal.Min
- Decimal.MinScale
- Decimal.Mul
- Decimal.MulExact
- Decimal.Neg
- Decimal.One
- Decimal.Pad
- Decimal.Pow
- Decimal.PowInt
- Decimal.Prec
- Decimal.Quantize
- Decimal.Quo
- Decimal.QuoExact
- Decimal.QuoRem
- Decimal.Rescale
- Decimal.Round
- Decimal.SameScale
- Decimal.Scale
- Decimal.Scan
- Decimal.Sign
- Decimal.Sqrt
- Decimal.String
- Decimal.Sub
- Decimal.SubAbs
- Decimal.SubExact
- Decimal.SubMul
- Decimal.SubMulExact
- Decimal.SubQuo
- Decimal.SubQuoExact
- Decimal.Trim
- Decimal.Trunc
- Decimal.ULP
- Decimal.UnmarshalBSONValue (Bson)
- Decimal.UnmarshalBinary (Gob)
- Decimal.UnmarshalJSON (Json)
- Decimal.UnmarshalText (Xml)
- Decimal.Value
- Decimal.WithinOne
- Decimal.WithinOne (Slices)
- Decimal.Zero
- Mean
- MustNew
- MustParse
- New
- NewFromFloat64
- NewFromInt64
- NullDecimal.MarshalBSONValue (Bson)
- NullDecimal.MarshalJSON (Json)
- NullDecimal.Scan
- NullDecimal.UnmarshalBSONValue (Bson)
- NullDecimal.UnmarshalJSON (Json)
- NullDecimal.Value
- Parse
- ParseExact
- Prod
- Sum
Constants ¶
const ( MaxPrec = 19 // MaxPrec is the maximum length of the coefficient in decimal digits. MinScale = 0 // MinScale is the minimum number of digits after the decimal point. MaxScale = 19 // MaxScale is the maximum number of digits after the decimal point. )
Variables ¶
var ( NegOne = MustNew(-1, 0) // NegOne represents the decimal value of -1. Zero = MustNew(0, 0) // Zero represents the decimal value of 0. For comparison purposes, use the IsZero method. One = MustNew(1, 0) // One represents the decimal value of 1. Two = MustNew(2, 0) // Two represents the decimal value of 2. Ten = MustNew(10, 0) // Ten represents the decimal value of 10. Hundred = MustNew(100, 0) // Hundred represents the decimal value of 100. Thousand = MustNew(1_000, 0) // Thousand represents the decimal value of 1,000. E = MustNew(2_718_281_828_459_045_235, 18) // E represents Euler’s number rounded to 18 digits. Pi = MustNew(3_141_592_653_589_793_238, 18) // Pi represents the value of π rounded to 18 digits. )
Functions ¶
This section is empty.
Types ¶
type Decimal ¶
type Decimal struct {
// contains filtered or unexported fields
}
Decimal represents a finite floating-point decimal number. Its zero value corresponds to the numeric value of 0. Decimal is designed to be safe for concurrent use by multiple goroutines.
func Mean ¶ added in v0.1.34
Mean returns the (possibly rounded) mean of decimals. It computes (d1 + d2 + ... + dn) / n with at least double precision during the intermediate rounding.
Mean returns an error if:
- no arguments are provided;
- the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") e := decimal.MustParse("-8") f := decimal.MustParse("23") fmt.Println(decimal.Mean(d, e, f)) }
Output: 6.89 <nil>
func MustNew ¶ added in v0.1.0
MustNew is like New but panics if the decimal cannot be constructed. It simplifies safe initialization of global variables holding decimals.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { fmt.Println(decimal.MustNew(567, 0)) fmt.Println(decimal.MustNew(567, 1)) fmt.Println(decimal.MustNew(567, 2)) fmt.Println(decimal.MustNew(567, 3)) fmt.Println(decimal.MustNew(567, 4)) }
Output: 567 56.7 5.67 0.567 0.0567
func MustParse ¶
MustParse is like Parse but panics if the string cannot be parsed. It simplifies safe initialization of global variables holding decimals.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { fmt.Println(decimal.MustParse("-1.23")) }
Output: -1.23
func New ¶
New returns a decimal equal to value / 10^scale. New keeps trailing zeros in the fractional part to preserve scale.
New returns an error if the scale is negative or greater than MaxScale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { fmt.Println(decimal.New(567, 0)) fmt.Println(decimal.New(567, 1)) fmt.Println(decimal.New(567, 2)) fmt.Println(decimal.New(567, 3)) fmt.Println(decimal.New(567, 4)) }
Output: 567 <nil> 56.7 <nil> 5.67 <nil> 0.567 <nil> 0.0567 <nil>
func NewFromFloat64 ¶ added in v0.1.5
NewFromFloat64 converts a float to a (possibly rounded) decimal. See also method Decimal.Float64.
NewFromFloat64 returns an error if:
- the float is a special value (NaN or Inf);
- the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { fmt.Println(decimal.NewFromFloat64(5.67e-2)) fmt.Println(decimal.NewFromFloat64(5.67e-1)) fmt.Println(decimal.NewFromFloat64(5.67e0)) fmt.Println(decimal.NewFromFloat64(5.67e1)) fmt.Println(decimal.NewFromFloat64(5.67e2)) }
Output: 0.0567 <nil> 0.567 <nil> 5.67 <nil> 56.7 <nil> 567 <nil>
func NewFromInt64 ¶ added in v0.1.4
NewFromInt64 converts a pair of integers, representing the whole and fractional parts, to a (possibly rounded) decimal equal to whole + frac / 10^scale. NewFromInt64 removes all trailing zeros from the fractional part. This method is useful for converting amounts from protobuf format. See also method Decimal.Int64.
NewFromInt64 returns an error if:
- the whole and fractional parts have different signs;
- the scale is negative or greater than MaxScale;
- frac / 10^scale is not within the range (-1, 1).
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { fmt.Println(decimal.NewFromInt64(5, 6, 1)) fmt.Println(decimal.NewFromInt64(5, 6, 2)) fmt.Println(decimal.NewFromInt64(5, 6, 3)) fmt.Println(decimal.NewFromInt64(5, 6, 4)) fmt.Println(decimal.NewFromInt64(5, 6, 5)) }
Output: 5.6 <nil> 5.06 <nil> 5.006 <nil> 5.0006 <nil> 5.00006 <nil>
func Parse ¶
Parse converts a string to a (possibly rounded) decimal. The input string must be in one of the following formats:
1.234 -1234 +0.000001234 1.83e5 0.22e-9
The formal EBNF grammar for the supported format is as follows:
sign ::= '+' | '-' digits ::= { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' } significand ::= digits '.' digits | '.' digits | digits '.' | digits exponent ::= ('e' | 'E') [sign] digits numeric-string ::= [sign] significand [exponent]
Parse removes leading zeros from the integer part of the input string, but tries to maintain trailing zeros in the fractional part to preserve scale.
Parse returns an error if:
- the string contains any whitespaces;
- the string is longer than 330 bytes;
- the exponent is less than -330 or greater than 330;
- the string does not represent a valid decimal number;
- the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { fmt.Println(decimal.Parse("5.67")) }
Output: 5.67 <nil>
func ParseExact ¶
ParseExact is similar to Parse, but it allows you to specify how many digits after the decimal point should be considered significant. If any of the significant digits are lost during rounding, the method will return an error. This method is useful for parsing monetary amounts, where the scale should be equal to or greater than the currency's scale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { fmt.Println(decimal.ParseExact("5.67", 0)) fmt.Println(decimal.ParseExact("5.67", 1)) fmt.Println(decimal.ParseExact("5.67", 2)) fmt.Println(decimal.ParseExact("5.67", 3)) fmt.Println(decimal.ParseExact("5.67", 4)) }
Output: 5.67 <nil> 5.67 <nil> 5.67 <nil> 5.670 <nil> 5.6700 <nil>
func Prod ¶ added in v0.1.33
Prod returns the (possibly rounded) product of decimals. It computes d1 * d2 * ... * dn with at least double precision during the intermediate rounding.
Prod returns an error if:
- no arguments are provided;
- the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") e := decimal.MustParse("-8") f := decimal.MustParse("23") fmt.Println(decimal.Prod(d, e, f)) }
Output: -1043.28 <nil>
func Sum ¶ added in v0.1.33
Sum returns the (possibly rounded) sum of decimals. It computes d1 + d2 + ... + dn without intermediate rounding.
Sum returns an error if:
- no argements are provided;
- the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") e := decimal.MustParse("-8") f := decimal.MustParse("23") fmt.Println(decimal.Sum(d, e, f)) }
Output: 20.67 <nil>
func (Decimal) Abs ¶
Abs returns the absolute value of the decimal.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-5.67") fmt.Println(d.Abs()) }
Output: 5.67
func (Decimal) Add ¶
Add returns the (possibly rounded) sum of decimals d and e.
Add returns an error if the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") e := decimal.MustParse("8") fmt.Println(d.Add(e)) }
Output: 13.67 <nil>
func (Decimal) AddExact ¶
AddExact is similar to Decimal.Add, but it allows you to specify the number of digits after the decimal point that should be considered significant. If any of the significant digits are lost during rounding, the method will return an error. This method is useful for financial calculations where the scale should be equal to or greater than the currency's scale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") e := decimal.MustParse("8") fmt.Println(d.AddExact(e, 0)) fmt.Println(d.AddExact(e, 1)) fmt.Println(d.AddExact(e, 2)) fmt.Println(d.AddExact(e, 3)) fmt.Println(d.AddExact(e, 4)) }
Output: 13.67 <nil> 13.67 <nil> 13.67 <nil> 13.670 <nil> 13.6700 <nil>
func (Decimal) AddMul ¶ added in v0.1.30
AddMul returns the (possibly rounded) fused multiply-addition of decimals d, e, and f. It computes d + e * f without any intermediate rounding. This method is useful for improving the accuracy and performance of algorithms that involve the accumulation of products, such as daily interest accrual.
AddMul returns an error if the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2") e := decimal.MustParse("3") f := decimal.MustParse("4") fmt.Println(d.AddMul(e, f)) }
Output: 14 <nil>
func (Decimal) AddMulExact ¶ added in v0.1.30
AddMulExact is similar to Decimal.AddMul, but it allows you to specify the number of digits after the decimal point that should be considered significant. If any of the significant digits are lost during rounding, the method will return an error. This method is useful for financial calculations where the scale should be equal to or greater than the currency's scale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2") e := decimal.MustParse("3") f := decimal.MustParse("4") fmt.Println(d.AddMulExact(e, f, 0)) fmt.Println(d.AddMulExact(e, f, 1)) fmt.Println(d.AddMulExact(e, f, 2)) fmt.Println(d.AddMulExact(e, f, 3)) fmt.Println(d.AddMulExact(e, f, 4)) }
Output: 14 <nil> 14.0 <nil> 14.00 <nil> 14.000 <nil> 14.0000 <nil>
func (Decimal) AddQuo ¶ added in v0.1.30
AddQuo returns the (possibly rounded) fused quotient-addition of decimals d, e, and f. It computes d + e / f with at least double precision during the intermediate rounding. This method is useful for improving the accuracy and performance of algorithms that involve the accumulation of quotients, such as internal rate of return.
AddQuo returns an error if:
- the divisor is 0;
- the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2") e := decimal.MustParse("3") f := decimal.MustParse("4") fmt.Println(d.AddQuo(e, f)) }
Output: 2.75 <nil>
func (Decimal) AddQuoExact ¶ added in v0.1.30
AddQuoExact is similar to Decimal.AddQuo, but it allows you to specify the number of digits after the decimal point that should be considered significant. If any of the significant digits are lost during rounding, the method will return an error. This method is useful for financial calculations where the scale should be equal to or greater than the currency's scale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2") e := decimal.MustParse("3") f := decimal.MustParse("4") fmt.Println(d.AddQuoExact(e, f, 0)) fmt.Println(d.AddQuoExact(e, f, 1)) fmt.Println(d.AddQuoExact(e, f, 2)) fmt.Println(d.AddQuoExact(e, f, 3)) fmt.Println(d.AddQuoExact(e, f, 4)) }
Output: 2.75 <nil> 2.75 <nil> 2.75 <nil> 2.750 <nil> 2.7500 <nil>
func (Decimal) Ceil ¶
Ceil returns a decimal rounded up to the given number of digits after the decimal point using rounding toward positive infinity. If the given scale is negative, it is redefined to zero. For financial calculations, the scale should be equal to or greater than the scale of the currency. See also method Decimal.Floor.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.678") fmt.Println(d.Ceil(0)) fmt.Println(d.Ceil(1)) fmt.Println(d.Ceil(2)) fmt.Println(d.Ceil(3)) fmt.Println(d.Ceil(4)) }
Output: 6 5.7 5.68 5.678 5.678
func (Decimal) Clamp ¶ added in v0.1.11
Clamp compares decimals and returns:
min if d < min max if d > max d otherwise
See also method Decimal.CmpTotal.
Clamp returns an error if min is greater than max numerically.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { min := decimal.MustParse("-20") max := decimal.MustParse("20") d := decimal.MustParse("-5.67") e := decimal.MustParse("0") f := decimal.MustParse("23") fmt.Println(d.Clamp(min, max)) fmt.Println(e.Clamp(min, max)) fmt.Println(f.Clamp(min, max)) }
Output: -5.67 <nil> 0 <nil> 20 <nil>
func (Decimal) Cmp ¶
Cmp compares decimals and returns:
-1 if d < e 0 if d = e +1 if d > e
See also methods Decimal.CmpAbs, Decimal.CmpTotal.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-23") e := decimal.MustParse("5.67") fmt.Println(d.Cmp(e)) fmt.Println(d.Cmp(d)) fmt.Println(e.Cmp(d)) }
Output: -1 0 1
Example (Slices) ¶
package main import ( "fmt" "slices" "github.com/govalues/decimal" ) func main() { s := []decimal.Decimal{ decimal.MustParse("-5.67"), decimal.MustParse("23"), decimal.MustParse("0"), } fmt.Println(slices.CompareFunc(s, s, decimal.Decimal.Cmp)) fmt.Println(slices.MaxFunc(s, decimal.Decimal.Cmp)) fmt.Println(slices.MinFunc(s, decimal.Decimal.Cmp)) fmt.Println(s, slices.IsSortedFunc(s, decimal.Decimal.Cmp)) slices.SortFunc(s, decimal.Decimal.Cmp) fmt.Println(s, slices.IsSortedFunc(s, decimal.Decimal.Cmp)) fmt.Println(slices.BinarySearchFunc(s, decimal.MustParse("1"), decimal.Decimal.Cmp)) }
Output: 0 23 -5.67 [-5.67 23 0] false [-5.67 0 23] true 2 false
func (Decimal) CmpAbs ¶ added in v0.1.10
CmpAbs compares absolute values of decimals and returns:
-1 if |d| < |e| 0 if |d| = |e| +1 if |d| > |e|
See also method Decimal.Cmp.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-23") e := decimal.MustParse("5.67") fmt.Println(d.CmpAbs(e)) fmt.Println(d.CmpAbs(d)) fmt.Println(e.CmpAbs(d)) }
Output: 1 0 -1
Example (Slices) ¶
package main import ( "fmt" "slices" "github.com/govalues/decimal" ) func main() { s := []decimal.Decimal{ decimal.MustParse("-5.67"), decimal.MustParse("23"), decimal.MustParse("0"), } fmt.Println(slices.CompareFunc(s, s, decimal.Decimal.CmpAbs)) fmt.Println(slices.MaxFunc(s, decimal.Decimal.CmpAbs)) fmt.Println(slices.MinFunc(s, decimal.Decimal.CmpAbs)) fmt.Println(s, slices.IsSortedFunc(s, decimal.Decimal.CmpAbs)) slices.SortFunc(s, decimal.Decimal.CmpAbs) fmt.Println(s, slices.IsSortedFunc(s, decimal.Decimal.CmpAbs)) fmt.Println(slices.BinarySearchFunc(s, decimal.MustParse("1"), decimal.Decimal.CmpAbs)) }
Output: 0 23 0 [-5.67 23 0] false [0 -5.67 23] true 1 false
func (Decimal) CmpTotal ¶
CmpTotal compares decimal representations and returns:
-1 if d < e -1 if d = e and d.scale > e.scale 0 if d = e and d.scale = e.scale +1 if d = e and d.scale < e.scale +1 if d > e
See also method Decimal.Cmp.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2.0") e := decimal.MustParse("2.00") fmt.Println(d.CmpTotal(e)) fmt.Println(d.CmpTotal(d)) fmt.Println(e.CmpTotal(d)) }
Output: 1 0 -1
Example (Slices) ¶
package main import ( "fmt" "slices" "github.com/govalues/decimal" ) func main() { s := []decimal.Decimal{ decimal.MustParse("-5.67"), decimal.MustParse("23"), decimal.MustParse("0"), } fmt.Println(slices.CompareFunc(s, s, decimal.Decimal.CmpTotal)) fmt.Println(slices.MaxFunc(s, decimal.Decimal.CmpTotal)) fmt.Println(slices.MinFunc(s, decimal.Decimal.CmpTotal)) fmt.Println(s, slices.IsSortedFunc(s, decimal.Decimal.CmpTotal)) slices.SortFunc(s, decimal.Decimal.CmpTotal) fmt.Println(s, slices.IsSortedFunc(s, decimal.Decimal.CmpTotal)) fmt.Println(slices.BinarySearchFunc(s, decimal.MustParse("10"), decimal.Decimal.CmpTotal)) }
Output: 0 23 -5.67 [-5.67 23 0] false [-5.67 0 23] true 2 false
func (Decimal) Coef ¶
Coef returns the coefficient of the decimal. See also method Decimal.Prec.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-123") e := decimal.MustParse("5.7") f := decimal.MustParse("0.4") fmt.Println(d.Coef()) fmt.Println(e.Coef()) fmt.Println(f.Coef()) }
Output: 123 57 4
func (Decimal) CopySign ¶ added in v0.0.7
CopySign returns a decimal with the same sign as decimal e. CopySign treates 0 as positive. See also method Decimal.Sign.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("23.00") e := decimal.MustParse("-5.67") fmt.Println(d.CopySign(e)) fmt.Println(e.CopySign(d)) }
Output: -23.00 5.67
func (Decimal) Equal ¶ added in v0.1.31
Equal compares decimals and returns:
true if d = e false otherwise
See also method Decimal.Cmp.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-23") e := decimal.MustParse("5.67") fmt.Println(d.Equal(e)) fmt.Println(d.Equal(d)) }
Output: false true
Example (Slices) ¶
package main import ( "fmt" "slices" "github.com/govalues/decimal" ) func main() { s := []decimal.Decimal{ decimal.MustParse("-5.67"), decimal.MustParse("0"), decimal.MustParse("0"), } fmt.Println(slices.EqualFunc(s, s, decimal.Decimal.Equal)) fmt.Println(slices.CompactFunc(s, decimal.Decimal.Equal)) }
Output: true [-5.67 0]
func (Decimal) Exp ¶ added in v0.1.30
Exp returns the (possibly rounded) exponential of a decimal.
Exp returns an error if the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-2.302585092994045684") e := decimal.MustParse("0") f := decimal.MustParse("2.302585092994045684") fmt.Println(d.Exp()) fmt.Println(e.Exp()) fmt.Println(f.Exp()) }
Output: 0.1000000000000000000 <nil> 1 <nil> 10.00000000000000000 <nil>
func (Decimal) Float64 ¶ added in v0.0.11
Float64 returns the nearest binary floating-point number rounded using rounding half to even (banker's rounding). See also constructor NewFromFloat64.
This conversion may lose data, as float64 has a smaller precision than the decimal type.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("0.1") e := decimal.MustParse("123.456") f := decimal.MustParse("1234567890.123456789") fmt.Println(d.Float64()) fmt.Println(e.Float64()) fmt.Println(f.Float64()) }
Output: 0.1 true 123.456 true 1.2345678901234567e+09 true
func (Decimal) Floor ¶
Floor returns a decimal rounded down to the specified number of digits after the decimal point using rounding toward negative infinity. If the given scale is negative, it is redefined to zero. For financial calculations, the scale should be equal to or greater than the scale of the currency. See also method Decimal.Ceil.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.678") fmt.Println(d.Floor(0)) fmt.Println(d.Floor(1)) fmt.Println(d.Floor(2)) fmt.Println(d.Floor(3)) fmt.Println(d.Floor(4)) }
Output: 5 5.6 5.67 5.678 5.678
func (Decimal) Format ¶
Format implements the fmt.Formatter interface. The following format verbs are available:
| Verb | Example | Description | | ---------- | ------- | -------------- | | %f, %s, %v | 5.67 | Decimal | | %q | "5.67" | Quoted decimal | | %k | 567% | Percentage |
The following format flags can be used with all verbs: '+', ' ', '0', '-'.
Precision is only supported for %f and %k verbs. For %f verb, the default precision is equal to the actual scale of the decimal, whereas, for verb %k the default precision is the actual scale of the decimal minus 2.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") fmt.Printf("%f\n", d) fmt.Printf("%k\n", d) }
Output: 5.67 567%
func (Decimal) Int64 ¶ added in v0.0.11
Int64 returns a pair of integers representing the whole and (possibly rounded) fractional parts of the decimal. If given scale is greater than the scale of the decimal, then the fractional part is zero-padded to the right. If given scale is smaller than the scale of the decimal, then the fractional part is rounded using rounding half to even (banker's rounding). The relationship between the decimal and the returned values can be expressed as d = whole + frac / 10^scale. This method is useful for converting amounts to protobuf format. See also constructor NewFromInt64.
If the result cannot be represented as a pair of int64 values, then false is returned.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") fmt.Println(d.Int64(0)) fmt.Println(d.Int64(1)) fmt.Println(d.Int64(2)) fmt.Println(d.Int64(3)) fmt.Println(d.Int64(4)) }
Output: 6 0 true 5 7 true 5 67 true 5 670 true 5 6700 true
func (Decimal) Inv ¶ added in v0.1.10
Inv returns the (possibly rounded) inverse of the decimal.
Inv returns an error if:
- the integer part of the result has more than MaxPrec digits;
- the decimal is 0.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2") fmt.Println(d.Inv()) }
Output: 0.5 <nil>
func (Decimal) IsInt ¶
IsInt returns true if there are no significant digits after the decimal point.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("1.00") e := decimal.MustParse("1.01") fmt.Println(d.IsInt()) fmt.Println(e.IsInt()) }
Output: true false
Example (Slices) ¶
package main import ( "fmt" "slices" "github.com/govalues/decimal" ) func main() { s := []decimal.Decimal{ decimal.MustParse("-5.67"), decimal.MustParse("23"), decimal.MustParse("0"), } fmt.Println(slices.ContainsFunc(s, decimal.Decimal.IsInt)) fmt.Println(slices.IndexFunc(s, decimal.Decimal.IsInt)) fmt.Println(slices.DeleteFunc(s, decimal.Decimal.IsInt)) }
Output: true 1 [-5.67]
func (Decimal) IsNeg ¶
IsNeg returns:
true if d < 0 false otherwise
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-5.67") e := decimal.MustParse("23") f := decimal.MustParse("0") fmt.Println(d.IsNeg()) fmt.Println(e.IsNeg()) fmt.Println(f.IsNeg()) }
Output: true false false
Example (Slices) ¶
package main import ( "fmt" "slices" "github.com/govalues/decimal" ) func main() { s := []decimal.Decimal{ decimal.MustParse("-5.67"), decimal.MustParse("23"), decimal.MustParse("0"), } fmt.Println(slices.ContainsFunc(s, decimal.Decimal.IsNeg)) fmt.Println(slices.IndexFunc(s, decimal.Decimal.IsNeg)) fmt.Println(slices.DeleteFunc(s, decimal.Decimal.IsNeg)) }
Output: true 0 [23 0]
func (Decimal) IsOne ¶
IsOne returns:
true if d = -1 or d = 1 false otherwise
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("1") e := decimal.MustParse("2") fmt.Println(d.IsOne()) fmt.Println(e.IsOne()) }
Output: true false
Example (Slices) ¶
package main import ( "fmt" "slices" "github.com/govalues/decimal" ) func main() { s := []decimal.Decimal{ decimal.MustParse("-5.67"), decimal.MustParse("23"), decimal.MustParse("1"), } fmt.Println(slices.ContainsFunc(s, decimal.Decimal.IsOne)) fmt.Println(slices.IndexFunc(s, decimal.Decimal.IsOne)) fmt.Println(slices.DeleteFunc(s, decimal.Decimal.IsOne)) }
Output: true 2 [-5.67 23]
func (Decimal) IsPos ¶
IsPos returns:
true if d > 0 false otherwise
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-5.67") e := decimal.MustParse("23") f := decimal.MustParse("0") fmt.Println(d.IsPos()) fmt.Println(e.IsPos()) fmt.Println(f.IsPos()) }
Output: false true false
Example (Slices) ¶
package main import ( "fmt" "slices" "github.com/govalues/decimal" ) func main() { s := []decimal.Decimal{ decimal.MustParse("-5.67"), decimal.MustParse("23"), decimal.MustParse("0"), } fmt.Println(slices.ContainsFunc(s, decimal.Decimal.IsPos)) fmt.Println(slices.IndexFunc(s, decimal.Decimal.IsPos)) fmt.Println(slices.DeleteFunc(s, decimal.Decimal.IsPos)) }
Output: true 1 [-5.67 0]
func (Decimal) IsZero ¶
IsZero returns:
true if d = 0 false otherwise
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-5.67") e := decimal.MustParse("23") f := decimal.MustParse("0") fmt.Println(d.IsZero()) fmt.Println(e.IsZero()) fmt.Println(f.IsZero()) }
Output: false false true
Example (Slices) ¶
package main import ( "fmt" "slices" "github.com/govalues/decimal" ) func main() { s := []decimal.Decimal{ decimal.MustParse("-5.67"), decimal.MustParse("23"), decimal.MustParse("0"), } fmt.Println(slices.ContainsFunc(s, decimal.Decimal.IsZero)) fmt.Println(slices.IndexFunc(s, decimal.Decimal.IsZero)) fmt.Println(slices.DeleteFunc(s, decimal.Decimal.IsZero)) }
Output: true 2 [-5.67 23]
func (Decimal) Less ¶ added in v0.1.31
Less compares decimals and returns:
true if d < e false otherwise
See also method Decimal.Cmp.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-23") e := decimal.MustParse("5.67") fmt.Println(d.Less(e)) fmt.Println(e.Less(d)) }
Output: true false
func (Decimal) Log ¶ added in v0.1.32
Log returns the (possibly rounded) natural logarithm of a decimal.
Log returns an error if the decimal is zero or negative.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("1") e := decimal.MustParse("2") f := decimal.MustParse("2.718281828459045236") g := decimal.MustParse("10") fmt.Println(d.Log()) fmt.Println(e.Log()) fmt.Println(f.Log()) fmt.Println(g.Log()) }
Output: 0 <nil> 0.6931471805599453094 <nil> 1.000000000000000000 <nil> 2.302585092994045684 <nil>
func (Decimal) Log10 ¶ added in v0.1.34
Log10 returns the (possibly rounded) decimal logarithm of a decimal.
Log10 returns an error if the decimal is zero or negative.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("1") e := decimal.MustParse("2") f := decimal.MustParse("2.718281828459045236") g := decimal.MustParse("10") fmt.Println(d.Log10()) fmt.Println(e.Log10()) fmt.Println(f.Log10()) fmt.Println(g.Log10()) }
Output: 0 <nil> 0.3010299956639811952 <nil> 0.4342944819032518278 <nil> 1 <nil>
func (Decimal) Log2 ¶ added in v0.1.34
Log2 returns the (possibly rounded) binary logarithm of a decimal.
Log2 returns an error if the decimal is zero or negative.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("1") e := decimal.MustParse("2") f := decimal.MustParse("2.718281828459045236") g := decimal.MustParse("10") fmt.Println(d.Log2()) fmt.Println(e.Log2()) fmt.Println(f.Log2()) fmt.Println(g.Log2()) }
Output: 0 <nil> 1 <nil> 1.442695040888963408 <nil> 3.321928094887362348 <nil>
func (Decimal) MarshalBSONValue ¶ added in v0.1.35
MarshalBSONValue implements the v2 bson.ValueMarshaler interface. MarshalBSONValue always returns decimal128.
Example (Bson) ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") t, data, err := d.MarshalBSONValue() fmt.Printf("%v [% x] %v\n", t, data, err) }
Output: 19 [37 02 00 00 00 00 00 00 00 00 00 00 00 00 3c 30] <nil>
func (Decimal) MarshalBinary ¶ added in v0.1.25
MarshalBinary implements the encoding.BinaryMarshaler interface. MarshalBinary always returns a numeric string. See also method Decimal.String.
Example (Gob) ¶
package main import ( "bytes" "encoding/gob" "fmt" "github.com/govalues/decimal" ) func marshalGOB(s string) ([]byte, error) { d, err := decimal.Parse(s) if err != nil { return nil, err } var data bytes.Buffer enc := gob.NewEncoder(&data) err = enc.Encode(d) if err != nil { return nil, err } return data.Bytes(), nil } func main() { data, err := marshalGOB("5.67") fmt.Printf("[% x] %v\n", data, err) }
Output: [12 7f 06 01 01 07 44 65 63 69 6d 61 6c 01 ff 80 00 00 00 08 ff 80 00 04 35 2e 36 37] <nil>
func (Decimal) MarshalJSON ¶ added in v0.1.35
MarshalJSON implements the json.Marshaler interface. MarshalJSON always returns a numeric string. See also method Decimal.String.
Example (Json) ¶
package main import ( "encoding/json" "fmt" "github.com/govalues/decimal" ) type Object struct { Number decimal.Decimal `json:"number"` } func marshalJSON(s string) (string, error) { d, err := decimal.Parse(s) if err != nil { return "", err } data, err := json.Marshal(Object{Number: d}) if err != nil { return "", err } return string(data), nil } func main() { fmt.Println(marshalJSON("5.67")) fmt.Println(marshalJSON("-5.67")) }
Output: {"number":"5.67"} <nil> {"number":"-5.67"} <nil>
func (Decimal) MarshalText ¶
MarshalText implements the encoding.TextMarshaler interface. MarshalText always returns a numeric string. See also method Decimal.String.
Example (Xml) ¶
package main import ( "encoding/xml" "fmt" "github.com/govalues/decimal" ) type Entity struct { Number decimal.Decimal `xml:"Number"` } func marshalXML(s string) (string, error) { d, err := decimal.Parse(s) if err != nil { return "", err } data, err := xml.Marshal(Entity{Number: d}) if err != nil { return "", err } return string(data), nil } func main() { fmt.Println(marshalXML("5.67")) fmt.Println(marshalXML("-5.67")) fmt.Println(marshalXML("5.67e-5")) fmt.Println(marshalXML("5.67e5")) }
Output: <Entity><Number>5.67</Number></Entity> <nil> <Entity><Number>-5.67</Number></Entity> <nil> <Entity><Number>0.0000567</Number></Entity> <nil> <Entity><Number>567000</Number></Entity> <nil>
func (Decimal) Max ¶
Max returns the larger decimal. See also method Decimal.CmpTotal.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("23") e := decimal.MustParse("-5.67") fmt.Println(d.Max(e)) }
Output: 23
func (Decimal) Min ¶
Min returns the smaller decimal. See also method Decimal.CmpTotal.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("23") e := decimal.MustParse("-5.67") fmt.Println(d.Min(e)) }
Output: -5.67
func (Decimal) MinScale ¶
MinScale returns the smallest scale that the decimal can be rescaled to without rounding. See also method Decimal.Trim.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("23.0000") e := decimal.MustParse("-5.6700") fmt.Println(d.MinScale()) fmt.Println(e.MinScale()) }
Output: 0 2
func (Decimal) Mul ¶
Mul returns the (possibly rounded) product of decimals d and e.
Mul returns an overflow error if the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.7") e := decimal.MustParse("3") fmt.Println(d.Mul(e)) }
Output: 17.1 <nil>
func (Decimal) MulExact ¶
MulExact is similar to Decimal.Mul, but it allows you to specify the number of digits after the decimal point that should be considered significant. If any of the significant digits are lost during rounding, the method will return an overflow error. This method is useful for financial calculations where the scale should be equal to or greater than the currency's scale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.7") e := decimal.MustParse("3") fmt.Println(d.MulExact(e, 0)) fmt.Println(d.MulExact(e, 1)) fmt.Println(d.MulExact(e, 2)) fmt.Println(d.MulExact(e, 3)) fmt.Println(d.MulExact(e, 4)) }
Output: 17.1 <nil> 17.1 <nil> 17.10 <nil> 17.100 <nil> 17.1000 <nil>
func (Decimal) Neg ¶
Neg returns a decimal with the opposite sign.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") fmt.Println(d.Neg()) }
Output: -5.67
func (Decimal) One ¶ added in v0.0.9
One returns a decimal with a value of 1, having the same scale as decimal d. See also methods Decimal.Zero, Decimal.ULP.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5") e := decimal.MustParse("5.6") f := decimal.MustParse("5.67") fmt.Println(d.One()) fmt.Println(e.One()) fmt.Println(f.One()) }
Output: 1 1.0 1.00
func (Decimal) Pad ¶ added in v0.1.0
Pad returns a decimal zero-padded to the specified number of digits after the decimal point. The total number of digits in the result is limited by MaxPrec. See also method Decimal.Trim.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") fmt.Println(d.Pad(0)) fmt.Println(d.Pad(1)) fmt.Println(d.Pad(2)) fmt.Println(d.Pad(3)) fmt.Println(d.Pad(4)) }
Output: 5.67 5.67 5.67 5.670 5.6700
func (Decimal) Pow ¶
Pow returns the (possibly rounded) decimal raised to the given decimal power. If zero is raised to zero power then the result is one.
Pow returns an error if:
- the integer part of the result has more than MaxPrec digits;
- zero is raised to a negative power;
- negative is raised to a fractional power.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("4") e := decimal.MustParse("0.5") f := decimal.MustParse("-0.5") fmt.Println(d.Pow(e)) fmt.Println(d.Pow(f)) }
Output: 2.000000000000000000 <nil> 0.5000000000000000000 <nil>
func (Decimal) PowInt ¶ added in v0.1.32
PowInt returns the (possibly rounded) decimal raised to the given integer power. If zero is raised to zero power then the result is one.
PowInt returns an error if:
- the integer part of the result has more than MaxPrec digits;
- zero is raised to a negative power.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2") fmt.Println(d.PowInt(-2)) fmt.Println(d.PowInt(-1)) fmt.Println(d.PowInt(0)) fmt.Println(d.PowInt(1)) fmt.Println(d.PowInt(2)) }
Output: 0.25 <nil> 0.5 <nil> 1 <nil> 2 <nil> 4 <nil>
func (Decimal) Prec ¶
Prec returns the number of digits in the coefficient. See also method Decimal.Coef.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-123") e := decimal.MustParse("5.7") f := decimal.MustParse("0.4") fmt.Println(d.Prec()) fmt.Println(e.Prec()) fmt.Println(f.Prec()) }
Output: 3 2 1
func (Decimal) Quantize ¶
Quantize returns a decimal rescaled to the same scale as decimal e. The sign and the coefficient of decimal e are ignored. See also methods Decimal.SameScale and Decimal.Rescale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.678") x := decimal.MustParse("1") y := decimal.MustParse("0.1") z := decimal.MustParse("0.01") fmt.Println(d.Quantize(x)) fmt.Println(d.Quantize(y)) fmt.Println(d.Quantize(z)) }
Output: 6 5.7 5.68
func (Decimal) Quo ¶
Quo returns the (possibly rounded) quotient of decimals d and e.
Quo returns an error if:
- the divisor is 0;
- the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") e := decimal.MustParse("2") fmt.Println(d.Quo(e)) }
Output: 2.835 <nil>
func (Decimal) QuoExact ¶
QuoExact is similar to Decimal.Quo, but it allows you to specify the number of digits after the decimal point that should be considered significant. If any of the significant digits are lost during rounding, the method will return an error. This method is useful for financial calculations where the scale should be equal to or greater than the currency's scale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.66") e := decimal.MustParse("2") fmt.Println(d.QuoExact(e, 0)) fmt.Println(d.QuoExact(e, 1)) fmt.Println(d.QuoExact(e, 2)) fmt.Println(d.QuoExact(e, 3)) fmt.Println(d.QuoExact(e, 4)) }
Output: 2.83 <nil> 2.83 <nil> 2.83 <nil> 2.830 <nil> 2.8300 <nil>
func (Decimal) QuoRem ¶
QuoRem returns the quotient q and remainder r of decimals d and e such that d = e * q + r, where q is an integer and the sign of the reminder r is the same as the sign of the dividend d.
QuoRem returns an error if:
- the divisor is 0;
- the integer part of the quotient has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") e := decimal.MustParse("2") fmt.Println(d.QuoRem(e)) }
Output: 2 1.67 <nil>
func (Decimal) Rescale ¶ added in v0.1.0
Rescale returns a decimal rounded or zero-padded to the given number of digits after the decimal point. If the given scale is negative, it is redefined to zero. For financial calculations, the scale should be equal to or greater than the scale of the currency. See also methods Decimal.Round, Decimal.Pad.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.678") fmt.Println(d.Rescale(0)) fmt.Println(d.Rescale(1)) fmt.Println(d.Rescale(2)) fmt.Println(d.Rescale(3)) fmt.Println(d.Rescale(4)) }
Output: 6 5.7 5.68 5.678 5.6780
func (Decimal) Round ¶
Round returns a decimal rounded to the specified number of digits after the decimal point using rounding half to even (banker's rounding). If the given scale is negative, it is redefined to zero. For financial calculations, the scale should be equal to or greater than the scale of the currency. See also method Decimal.Rescale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.678") fmt.Println(d.Round(0)) fmt.Println(d.Round(1)) fmt.Println(d.Round(2)) fmt.Println(d.Round(3)) fmt.Println(d.Round(4)) }
Output: 6 5.7 5.68 5.678 5.678
func (Decimal) SameScale ¶ added in v0.1.17
SameScale returns true if decimals have the same scale. See also methods Decimal.Scale, Decimal.Quantize.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { a := decimal.MustParse("23") b := decimal.MustParse("5.67") c := decimal.MustParse("1.23") fmt.Println(a.SameScale(b)) fmt.Println(b.SameScale(c)) }
Output: false true
func (Decimal) Scale ¶
Scale returns the number of digits after the decimal point. See also methods Decimal.Prec, Decimal.MinScale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("23") e := decimal.MustParse("5.67") fmt.Println(d.Scale()) fmt.Println(e.Scale()) }
Output: 0 2
func (*Decimal) Scan ¶ added in v0.1.6
Scan implements the sql.Scanner interface.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { var d decimal.Decimal _ = d.Scan("5.67") fmt.Println(d) }
Output: 5.67
func (Decimal) Sign ¶
Sign returns:
-1 if d < 0 0 if d = 0 +1 if d > 0
See also methods Decimal.IsPos, Decimal.IsNeg, Decimal.IsZero.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-5.67") e := decimal.MustParse("23") f := decimal.MustParse("0") fmt.Println(d.Sign()) fmt.Println(e.Sign()) fmt.Println(f.Sign()) }
Output: -1 1 0
func (Decimal) Sqrt ¶ added in v0.1.28
Sqrt computes the (possibly rounded) square root of a decimal. d.Sqrt() is significantly faster than d.Pow(0.5).
Sqrt returns an error if the decimal is negative.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("1") e := decimal.MustParse("2") f := decimal.MustParse("3") g := decimal.MustParse("4") fmt.Println(d.Sqrt()) fmt.Println(e.Sqrt()) fmt.Println(f.Sqrt()) fmt.Println(g.Sqrt()) }
Output: 1 <nil> 1.414213562373095049 <nil> 1.732050807568877294 <nil> 2 <nil>
func (Decimal) String ¶
String implements the fmt.Stringer interface and returns a string representation of the decimal. The returned string does not use scientific or engineering notation and is formatted according to the following formal EBNF grammar:
sign ::= '-' digits ::= { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' } significand ::= digits '.' digits | digits numeric-string ::= [sign] significand
See also method Decimal.Format.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("1234567890.123456789") fmt.Println(d.String()) }
Output: 1234567890.123456789
func (Decimal) Sub ¶
Sub returns the (possibly rounded) difference between decimals d and e.
Sub returns an error if the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-5.67") e := decimal.MustParse("8") fmt.Println(d.Sub(e)) }
Output: -13.67 <nil>
func (Decimal) SubAbs ¶ added in v0.1.10
SubAbs returns the (possibly rounded) absolute difference between decimals d and e.
SubAbs returns an error if the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("-5.67") e := decimal.MustParse("8") fmt.Println(d.SubAbs(e)) }
Output: 13.67 <nil>
func (Decimal) SubExact ¶
SubExact is similar to Decimal.Sub, but it allows you to specify the number of digits after the decimal point that should be considered significant. If any of the significant digits are lost during rounding, the method will return an error. This method is useful for financial calculations where the scale should be equal to or greater than the currency's scale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("8") e := decimal.MustParse("5.67") fmt.Println(d.SubExact(e, 0)) fmt.Println(d.SubExact(e, 1)) fmt.Println(d.SubExact(e, 2)) fmt.Println(d.SubExact(e, 3)) fmt.Println(d.SubExact(e, 4)) }
Output: 2.33 <nil> 2.33 <nil> 2.33 <nil> 2.330 <nil> 2.3300 <nil>
func (Decimal) SubMul ¶ added in v0.1.31
SubMul returns the (possibly rounded) fused multiply-subtraction of decimals d, e, and f. It computes d - e * f without any intermediate rounding. This method is useful for improving the accuracy and performance of algorithms that involve the accumulation of products, such as daily interest accrual.
SubMul returns an error if the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2") e := decimal.MustParse("3") f := decimal.MustParse("4") fmt.Println(d.SubMul(e, f)) }
Output: -10 <nil>
func (Decimal) SubMulExact ¶ added in v0.1.31
SubMulExact is similar to Decimal.SubMul, but it allows you to specify the number of digits after the decimal point that should be considered significant. If any of the significant digits are lost during rounding, the method will return an error. This method is useful for financial calculations where the scale should be equal to or greater than the currency's scale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2") e := decimal.MustParse("3") f := decimal.MustParse("4") fmt.Println(d.SubMulExact(e, f, 0)) fmt.Println(d.SubMulExact(e, f, 1)) fmt.Println(d.SubMulExact(e, f, 2)) fmt.Println(d.SubMulExact(e, f, 3)) fmt.Println(d.SubMulExact(e, f, 4)) }
Output: -10 <nil> -10.0 <nil> -10.00 <nil> -10.000 <nil> -10.0000 <nil>
func (Decimal) SubQuo ¶ added in v0.1.31
SubQuo returns the (possibly rounded) fused quotient-subtraction of decimals d, e, and f. It computes d - e / f with at least double precision during intermediate rounding. This method is useful for improving the accuracy and performance of algorithms that involve the accumulation of quotients, such as internal rate of return.
AddQuo returns an error if:
- the divisor is 0;
- the integer part of the result has more than MaxPrec digits.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2") e := decimal.MustParse("3") f := decimal.MustParse("4") fmt.Println(d.SubQuo(e, f)) }
Output: 1.25 <nil>
func (Decimal) SubQuoExact ¶ added in v0.1.31
SubQuoExact is similar to Decimal.SubQuo, but it allows you to specify the number of digits after the decimal point that should be considered significant. If any of the significant digits are lost during rounding, the method will return an error. This method is useful for financial calculations where the scale should be equal to or greater than the currency's scale.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("2") e := decimal.MustParse("3") f := decimal.MustParse("4") fmt.Println(d.SubQuoExact(e, f, 0)) fmt.Println(d.SubQuoExact(e, f, 1)) fmt.Println(d.SubQuoExact(e, f, 2)) fmt.Println(d.SubQuoExact(e, f, 3)) fmt.Println(d.SubQuoExact(e, f, 4)) }
Output: 1.25 <nil> 1.25 <nil> 1.25 <nil> 1.250 <nil> 1.2500 <nil>
func (Decimal) Trim ¶ added in v0.1.0
Trim returns a decimal with trailing zeros removed up to the given number of digits after the decimal point. If the given scale is negative, it is redefined to zero. See also method Decimal.Pad.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("23.400") fmt.Println(d.Trim(0)) fmt.Println(d.Trim(1)) fmt.Println(d.Trim(2)) fmt.Println(d.Trim(3)) fmt.Println(d.Trim(4)) }
Output: 23.4 23.4 23.40 23.400 23.400
func (Decimal) Trunc ¶
Trunc returns a decimal truncated to the specified number of digits after the decimal point using rounding toward zero. If the given scale is negative, it is redefined to zero. For financial calculations, the scale should be equal to or greater than the scale of the currency.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.678") fmt.Println(d.Trunc(0)) fmt.Println(d.Trunc(1)) fmt.Println(d.Trunc(2)) fmt.Println(d.Trunc(3)) fmt.Println(d.Trunc(4)) }
Output: 5 5.6 5.67 5.678 5.678
func (Decimal) ULP ¶ added in v0.0.6
ULP (Unit in the Last Place) returns the smallest representable positive difference between two decimals with the same scale as decimal d. It can be useful for implementing rounding and comparison algorithms. See also methods Decimal.Zero, Decimal.One.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5") e := decimal.MustParse("5.6") f := decimal.MustParse("5.67") fmt.Println(d.ULP()) fmt.Println(e.ULP()) fmt.Println(f.ULP()) }
Output: 1 0.1 0.01
func (*Decimal) UnmarshalBSONValue ¶ added in v0.1.35
UnmarshalBSONValue implements the v2 bson.ValueUnmarshaler interface. UnmarshalBSONValue supports the following BSON types: double, string, int32, int64, and decimal128.
Example (Bson) ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { data := []byte{ 0x37, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, } var d decimal.Decimal err := d.UnmarshalBSONValue(19, data) fmt.Println(d, err) }
Output: 5.67 <nil>
func (*Decimal) UnmarshalBinary ¶ added in v0.1.25
UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. UnmarshalBinary supports only numeric strings. See also constructor Parse.
Example (Gob) ¶
package main import ( "bytes" "encoding/gob" "fmt" "github.com/govalues/decimal" ) func unmarshalGOB(data []byte) (decimal.Decimal, error) { var d decimal.Decimal dec := gob.NewDecoder(bytes.NewReader(data)) err := dec.Decode(&d) if err != nil { return decimal.Decimal{}, err } return d, nil } func main() { data := []byte{ 0x12, 0x7f, 0x06, 0x01, 0x01, 0x07, 0x44, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x08, 0xff, 0x80, 0x00, 0x04, 0x35, 0x2e, 0x36, 0x37, } fmt.Println(unmarshalGOB(data)) }
Output: 5.67 <nil>
func (*Decimal) UnmarshalJSON ¶ added in v0.1.35
UnmarshalJSON implements the json.Unmarshaler interface. UnmarshalJSON supports the following JSON types: number and numeric string. See also constructor Parse.
Example (Json) ¶
package main import ( "encoding/json" "fmt" "github.com/govalues/decimal" ) type Object struct { Number decimal.Decimal `json:"number"` } func unmarshalJSON(s string) (Object, error) { var o Object err := json.Unmarshal([]byte(s), &o) if err != nil { return Object{}, err } return o, nil } func main() { fmt.Println(unmarshalJSON(`{"number":"5.67"}`)) fmt.Println(unmarshalJSON(`{"number":"-5.67"}`)) fmt.Println(unmarshalJSON(`{"number":5.67e-5}`)) fmt.Println(unmarshalJSON(`{"number":5.67e5}`)) }
Output: {5.67} <nil> {-5.67} <nil> {0.0000567} <nil> {567000} <nil>
func (*Decimal) UnmarshalText ¶
UnmarshalText implements the encoding.TextUnmarshaler interface. UnmarshalBinary supports only numeric strings. See also constructor Parse.
Example (Xml) ¶
package main import ( "encoding/xml" "fmt" "github.com/govalues/decimal" ) type Entity struct { Number decimal.Decimal `xml:"Number"` } func unmarshalXML(s string) (Entity, error) { var e Entity err := xml.Unmarshal([]byte(s), &e) return e, err } func main() { fmt.Println(unmarshalXML(`<Entity><Number>5.67</Number></Entity>`)) fmt.Println(unmarshalXML(`<Entity><Number>-5.67</Number></Entity>`)) fmt.Println(unmarshalXML(`<Entity><Number>5.67e-5</Number></Entity>`)) fmt.Println(unmarshalXML(`<Entity><Number>5.67e5</Number></Entity>`)) }
Output: {5.67} <nil> {-5.67} <nil> {0.0000567} <nil> {567000} <nil>
func (Decimal) Value ¶ added in v0.1.6
Value implements the driver.Valuer interface.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5.67") fmt.Println(d.Value()) }
Output: 5.67 <nil>
func (Decimal) WithinOne ¶ added in v0.0.9
WithinOne returns:
true if -1 < d < 1 false otherwise
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("1") e := decimal.MustParse("0.9") f := decimal.MustParse("-0.9") g := decimal.MustParse("-1") fmt.Println(d.WithinOne()) fmt.Println(e.WithinOne()) fmt.Println(f.WithinOne()) fmt.Println(g.WithinOne()) }
Output: false true true false
Example (Slices) ¶
package main import ( "fmt" "slices" "github.com/govalues/decimal" ) func main() { s := []decimal.Decimal{ decimal.MustParse("-5.67"), decimal.MustParse("23"), decimal.MustParse("0.1"), } fmt.Println(slices.ContainsFunc(s, decimal.Decimal.WithinOne)) fmt.Println(slices.IndexFunc(s, decimal.Decimal.WithinOne)) fmt.Println(slices.DeleteFunc(s, decimal.Decimal.WithinOne)) }
Output: true 2 [-5.67 23]
func (Decimal) Zero ¶ added in v0.0.9
Zero returns a decimal with a value of 0, having the same scale as decimal d. See also methods Decimal.One, Decimal.ULP.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("5") e := decimal.MustParse("5.6") f := decimal.MustParse("5.67") fmt.Println(d.Zero()) fmt.Println(e.Zero()) fmt.Println(f.Zero()) }
Output: 0 0.0 0.00
type NullDecimal ¶ added in v0.1.13
NullDecimal represents a decimal that can be null. Its zero value is null. NullDecimal is not thread-safe.
func (NullDecimal) MarshalBSONValue ¶ added in v0.1.35
func (n NullDecimal) MarshalBSONValue() (typ byte, data []byte, err error)
MarshalBSONValue implements the v2 bson.ValueMarshaler interface. MarshalBSONValue always returns the following BSON types: decimal128 or null. See also method Decimal.MarshalBSONValue.
Example (Bson) ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { n := decimal.NullDecimal{ Valid: false, } t, data, _ := n.MarshalBSONValue() fmt.Printf("%v [% x]\n", t, data) m := decimal.NullDecimal{ Decimal: decimal.MustParse("5.67"), Valid: true, } t, data, _ = m.MarshalBSONValue() fmt.Printf("%v [% x]\n", t, data) }
Output: 10 [] 19 [37 02 00 00 00 00 00 00 00 00 00 00 00 00 3c 30]
func (NullDecimal) MarshalJSON ¶ added in v0.1.35
func (n NullDecimal) MarshalJSON() ([]byte, error)
MarshalJSON implements the json.Marshaler interface. See also method Decimal.MarshalJSON.
Example (Json) ¶
package main import ( "encoding/json" "fmt" "github.com/govalues/decimal" ) func main() { n := decimal.NullDecimal{ Valid: false, } data, _ := json.Marshal(n) fmt.Println(string(data)) m := decimal.NullDecimal{ Decimal: decimal.MustParse("5.67"), Valid: true, } data, _ = json.Marshal(m) fmt.Println(string(data)) }
Output: null "5.67"
func (*NullDecimal) Scan ¶ added in v0.1.13
func (n *NullDecimal) Scan(value any) error
Scan implements the sql.Scanner interface. See also method Decimal.Scan.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { var n decimal.NullDecimal _ = n.Scan(nil) fmt.Println(n) var m decimal.NullDecimal _ = m.Scan("5.67") fmt.Println(m) }
Output: {0 false} {5.67 true}
func (*NullDecimal) UnmarshalBSONValue ¶ added in v0.1.35
func (n *NullDecimal) UnmarshalBSONValue(typ byte, data []byte) error
UnmarshalBSONValue implements the v2 bson.ValueUnmarshaler interface. UnmarshalBSONValue supports the following BSON types: double, string, null, int32, int64, and decimal128. See also method Decimal.UnmarshalBSONValue.
Example (Bson) ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { var n decimal.NullDecimal _ = n.UnmarshalBSONValue(10, nil) fmt.Println(n) data := []byte{ 0x37, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, } var m decimal.NullDecimal _ = m.UnmarshalBSONValue(19, data) fmt.Println(m) }
Output: {0 false} {5.67 true}
func (*NullDecimal) UnmarshalJSON ¶ added in v0.1.35
func (n *NullDecimal) UnmarshalJSON(data []byte) error
UnmarshalJSON implements the json.Unmarshaler interface. See also method Decimal.UnmarshalJSON.
Example (Json) ¶
package main import ( "encoding/json" "fmt" "github.com/govalues/decimal" ) func main() { var n decimal.NullDecimal _ = json.Unmarshal([]byte(`null`), &n) fmt.Println(n) var m decimal.NullDecimal _ = json.Unmarshal([]byte(`"5.67"`), &m) fmt.Println(m) }
Output: {0 false} {5.67 true}
func (NullDecimal) Value ¶ added in v0.1.13
func (n NullDecimal) Value() (driver.Value, error)
Value implements the driver.Valuer interface. See also method Decimal.Value.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { n := decimal.NullDecimal{ Valid: false, } fmt.Println(n.Value()) m := decimal.NullDecimal{ Decimal: decimal.MustParse("5.67"), Valid: true, } fmt.Println(m.Value()) }
Output: <nil> <nil> 5.67 <nil>