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.
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 ¶
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.
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 increased 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 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:
- Decimal.Add, Decimal.Sub, Decimal.Mul, Decimal.FMA, Decimal.Pow, Decimal.Quo, Decimal.QuoRem, Decimal.Inv: All digits in the integer part are significant, while digits in the fractional part are considered insignificant.
- Decimal.AddExact, Decimal.SubExact, Decimal.MulExact, Decimal.FMAExact, Decimal.PowExact, Decimal.QuoExact: 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.
Context ¶
Unlike many other decimal libraries, this package does not provide an explicit 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 ¶
Implicit rounding is applied when a result exceeds 19 digits, rounding it to 19 digits using half-to-even rounding. This method ensures that rounding errors are evenly distributed between rounding up and down.
For all arithmetic operations, except for Decimal.Pow and Decimal.PowExact, the result is the one that would be obtained by computing the exact mathematical result with infinite precision and then rounding it to 19 digits. Decimal.Pow and Decimal.PowExact may occasionally produce a result that is off by 1 unit in the last place.
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.
Errors ¶
All methods are panic-free and pure. Errors are returned in the following cases:
Division by Zero. Unlike the standard library, Decimal.Quo, Decimal.QuoRem, and Decimal.Inv do not panic when dividing by 0. Instead, they return an error.
Invalid Operation. Decimal.Pow and Decimal.PowExact return an error if 0 is raised to a negative power.
Overflow. Unlike standard integers, there is no "wrap around" for decimals at certain sizes. For out-of-range values, arithmetic operations return an error.
Errors are not returned in the following cases:
- Underflow. Arithmetic operations do not return an error in case of decimal underflow. If the result is a decimal between -0.00000000000000000005 and 0.00000000000000000005 inclusive, it will be rounded to 0.
Conversions ¶
JSON.
The package integrates seamlessly with standard encoding/json through the implementation of encoding.TextMarshaller and encoding.TextUnmarshaler interfaces. Here is an example structure:
type Object struct { Number decimal.Decimal `json:"some_number"` // Other fields... }
The package marshals decimals as quoted strings, ensuring the preservation of the exact numerical value. Here is an example OpenAPI schema:
Decimal: type: string format: decimal pattern: '^(\-|\+)?((\d+(\.\d*)?)|(\.\d+))$'
XML.
The package integrates with standard encoding/xml via the implementation of encoding.TextMarshaller and encoding.TextUnmarshaler interfaces. Here is an example structure:
type Entity struct { Number decimal.Decimal `xml:"SomeNumber"` // Other fields... }
"xs:decimal" type can be used to 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>
Protocol Buffers.
Protocol Buffers can represent decimals as numerical strings, preserving trailing zeros. To convert between numerical strings and decimals, use Parse and Decimal.String. Here is an example proto definition:
message Decimal { string value = 1; }
Alternatively, decimals can be represented as two integers: one for the integer part and another for the fractional part. For conversion between this format and decimals, use NewFromInt64 and Decimal.Int64 with a scale argument equal to "9". Here is an example proto definition:
message Decimal { int64 units = 1; int32 nanos = 2; }
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) |
Here are the reasons:
For PostgreSQL, always use DECIMAL without precision or scale specifications (avoid DECIMAL(p) or DECIMAL(p, s)). DECIMAL accurately preserves the scale of decimals.
In SQLite, prefer TEXT, since DECIMAL is just an alias for floating-point numbers. TEXT preserves the scale of decimals.
In MySQL, use DECIMAL(19, d), as DECIMAL is just an alias for DECIMAL(10, 0). The disadvantage of this format is that MySQL automatically rescales all decimals: values with a scale exceeding "d" are rounded (using half away from zero), while those with a lower scale are padded with trailing zeros. To avoid automatic rescaling, consider using VARCHAR(22).
Example (FloatInaccuracy) ¶
This example demonstrates the advantage of decimals for financial calculations. It computes the sum 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1. In decimal arithmetic, the result is exactly 1.0. In float64 arithmetic, the result slightly deviates from 1.0 due to binary floating-point representation.
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { d := decimal.MustParse("0.0") e := decimal.MustParse("0.1") for i := 0; i < 10; i++ { d, _ = d.Add(e) } fmt.Println(d) f := 0.0 for i := 0; i < 10; i++ { f += 0.1 } fmt.Println(f) }
Output: 1.0 0.9999999999999999
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 approximate(terms int) (decimal.Decimal, error) { pi := decimal.Zero denominator := decimal.One increment := decimal.Two multiplier := decimal.MustParse("4") for i := 0; i < terms; i++ { term, err := multiplier.Quo(denominator) if err != nil { return decimal.Decimal{}, err } pi, err = pi.Add(term) 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 } func main() { pi, err := approximate(500000) if err != nil { panic(err) } fmt.Println(pi) fmt.Println(decimal.Pi) }
Output: 3.141590653589793206 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 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 } func main() { d, err := evaluate("1.23 4.56 + 10 *") if err != nil { panic(err) } fmt.Println(d) }
Output: 57.90
Index ¶
- Constants
- Variables
- type Decimal
- func MustNew(coef int64, scale int) Decimal
- func MustParse(s string) Decimal
- func New(coef 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 (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) 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) FMA(e, f Decimal) (Decimal, error)
- func (d Decimal) FMAExact(e, f Decimal, scale int) (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) 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, error)
- func (d Decimal) Pow(power int) (Decimal, error)
- func (d Decimal) PowExact(power, scale int) (Decimal, error)
- func (d Decimal) Prec() int
- func (d Decimal) Quantize(e Decimal) (Decimal, error)
- 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, error)
- 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) 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) Trim(scale int) Decimal
- func (d Decimal) Trunc(scale int) Decimal
- func (d Decimal) ULP() Decimal
- 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
Examples ¶
- Package (FloatInaccuracy)
- Package (PiApproximation)
- Package (PostfixCalculator)
- Decimal.Abs
- Decimal.Add
- Decimal.AddExact
- Decimal.Ceil
- Decimal.Clamp
- Decimal.Cmp
- Decimal.CmpAbs
- Decimal.CmpTotal
- Decimal.Coef
- Decimal.CopySign
- Decimal.FMA
- Decimal.FMAExact
- Decimal.Float64
- Decimal.Floor
- Decimal.Format
- Decimal.Int64
- Decimal.Inv
- Decimal.IsInt
- Decimal.IsNeg
- Decimal.IsOne
- Decimal.IsPos
- Decimal.IsZero
- Decimal.MarshalText (Json)
- Decimal.MarshalText (Xml)
- Decimal.Max
- Decimal.Min
- Decimal.MinScale
- Decimal.Mul
- Decimal.MulExact
- Decimal.Neg
- Decimal.One
- Decimal.Pad
- Decimal.Pow
- Decimal.PowExact
- Decimal.Prec
- Decimal.Quantize
- Decimal.Quo
- Decimal.QuoExact
- Decimal.QuoRem
- Decimal.Rescale
- Decimal.Round
- Decimal.SameScale
- Decimal.Scale
- Decimal.Scan
- Decimal.Sign
- Decimal.String
- Decimal.Sub
- Decimal.SubAbs
- Decimal.SubExact
- Decimal.Trim
- Decimal.Trunc
- Decimal.ULP
- Decimal.UnmarshalText (Json)
- Decimal.UnmarshalText (Xml)
- Decimal.Value
- Decimal.WithinOne
- Decimal.Zero
- MustNew
- MustParse
- New
- NewFromFloat64
- NewFromInt64
- NullDecimal.Scan
- NullDecimal.Value
- Parse
- ParseExact
Constants ¶
const ( MaxPrec = 19 // MaxPrec is a maximum length of the coefficient in decimal digits. MinScale = 0 // MinScale is a minimum number of digits after the decimal point. MaxScale = 19 // MaxScale is a 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. 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 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 coef / 10^scale. New keeps trailing zeros in the fractional part to preserve scale.
New returns an error if 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 (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) 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
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
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
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) FMA ¶ added in v0.0.3
FMA 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.
FMA 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("2") e := decimal.MustParse("3") f := decimal.MustParse("4") fmt.Println(d.FMA(e, f)) }
Output: 10 <nil>
func (Decimal) FMAExact ¶ added in v0.0.3
FMAExact is similar to Decimal.FMA, 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.FMAExact(e, f, 0)) fmt.Println(d.FMAExact(e, f, 1)) fmt.Println(d.FMAExact(e, f, 2)) fmt.Println(d.FMAExact(e, f, 3)) fmt.Println(d.FMAExact(e, f, 4)) }
Output: 10 <nil> 10.0 <nil> 10.00 <nil> 10.000 <nil> 10.0000 <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
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
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
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
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
func (Decimal) MarshalText ¶
MarshalText implements the encoding.TextMarshaler interface. 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 } v := Object{Number: d} b, err := json.Marshal(v) if err != nil { return "", err } return string(b), nil } func main() { fmt.Println(marshalJSON("5.67")) fmt.Println(marshalJSON("-5.67")) fmt.Println(marshalJSON("5.67e-5")) fmt.Println(marshalJSON("5.67e5")) }
Output: {"number":"5.67"} <nil> {"number":"-5.67"} <nil> {"number":"0.0000567"} <nil> {"number":"567000"} <nil>
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 } v := Entity{Number: d} b, err := xml.Marshal(v) if err != nil { return "", err } return string(b), 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. See also method Decimal.Trim.
Pad returns an error if the integer part of the result has more than (MaxPrec - scale) digits.
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 <nil> 5.67 <nil> 5.67 <nil> 5.670 <nil> 5.6700 <nil>
func (Decimal) Pow ¶
Pow returns the (possibly rounded) decimal raised to the given power.
Pow 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.Pow(-2)) fmt.Println(d.Pow(-1)) fmt.Println(d.Pow(0)) fmt.Println(d.Pow(1)) fmt.Println(d.Pow(2)) }
Output: 0.25 <nil> 0.5 <nil> 1 <nil> 2 <nil> 4 <nil>
func (Decimal) PowExact ¶ added in v0.1.0
PowExact is similar to Decimal.Pow, 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("2") fmt.Println(d.PowExact(3, 0)) fmt.Println(d.PowExact(3, 1)) fmt.Println(d.PowExact(3, 2)) fmt.Println(d.PowExact(3, 3)) fmt.Println(d.PowExact(3, 4)) }
Output: 8 <nil> 8.0 <nil> 8.00 <nil> 8.000 <nil> 8.0000 <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.Scale, Decimal.SameScale, Decimal.Rescale.
Qunatize returns an overflow error if the integer part of result has more than (MaxPrec - e.Scale()) digits.
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 <nil> 5.7 <nil> 5.68 <nil>
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. For financial calculations, the scale should be equal to or greater than the scale of the currency. See also methods Decimal.Round, Decimal.Pad.
Rescale returns an overflow error if the integer part of the result has more than (MaxPrec - scale) digits.
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 <nil> 5.7 <nil> 5.68 <nil> 5.678 <nil> 5.6780 <nil>
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. See also constructor Parse.
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
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) 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) 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) UnmarshalText ¶
UnmarshalText implements the encoding.TextUnmarshaler interface. 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 v Object err := json.Unmarshal([]byte(s), &v) return v, err } 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>
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 v Entity err := xml.Unmarshal([]byte(s), &v) return v, 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. See also method Decimal.String.
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
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) Scan ¶ added in v0.1.13
func (n *NullDecimal) Scan(value any) error
Scan implements the sql.Scanner interface. See also constructor Parse.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { var n, m decimal.NullDecimal _ = n.Scan("5.67") _ = m.Scan(nil) fmt.Println(n) fmt.Println(m) }
Output: {5.67 true} {0 false}
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.String.
Example ¶
package main import ( "fmt" "github.com/govalues/decimal" ) func main() { n := decimal.NullDecimal{ Decimal: decimal.MustParse("5.67"), Valid: true, } m := decimal.NullDecimal{ Decimal: decimal.MustParse("0"), Valid: false, } fmt.Println(n.Value()) fmt.Println(m.Value()) }
Output: 5.67 <nil> <nil> <nil>