decimal

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2026 License: MIT Imports: 12 Imported by: 0

README

decimal

ci Go Reference Go Coverage lint Mentioned in Awesome Go

High performance, zero-allocation, low memory usage (8 bytes), low precision (17 digits), partially compatible with int64 and shopspring/decimal

Features

  • the unitialized value is Null and is safe to use without initialization, intepreted as 0 which is different from 0, usefull in omitempty flag for JSON decoding/encoding.
  • low-memory usage as internal representation is int64 and value between -144115188075855871 and 144115188075855871 can safely be used as Decimal.
  • no heap allocations to prevent garbage collector impact.
  • high performance, fractional arithmetic is 4× to 19× faster than shopspring/decimal v1.6, pure-integer arithmetic 11× to 26×, trigonometric functions ~40× to ~95×, Ln ~45× and Sqrt ~15× — all allocation-free, where shopspring allocates on every operation (see Benchmarks below).
  • compact binary serialization from 1 to 10 bytes — open, documented, interoperable format (see BINARY_FORMAT.md; same format covers Weight and Length with explicit unit support).
  • 57 bits mantissa to limit rounding errors compared to float64 (50 bits mantissa) for common operation like additions, multiplications, divisions.
  • loss flag available so if a rounding error occurs information is not lost.
  • support infinity and NaN decimal as well as near zero value, near negative zero and near positive zero (loss bit always set in such cases).
  • since int64 is used internally, Decimal are immutable as no internal pointer is used.
  • unique representation for a given decimal, suitable for use as a key in hash table or by using == or != operator directly.
  • support Weight and Length decimal using 53 bits mantissa and 4 bits of type unit.
  • JSON, XML - compatible with [encoding/json] and [encoding/xml].
  • compatible with shopspring/decimal except for BigInt and BigRat methods not supported.

Install

Run go get github.com/aytechnet/decimal

Requirements

Decimal library requires Go version >=1.13.

Documentation

http://godoc.org/github.com/aytechnet/decimal

Usage

Usage taken from shopspring/decimal but updated for this package and constant compatibility with int64 :

package main

import (
	"fmt"
	"github.com/aytechnet/decimal"
)

func main() {
	price, err := decimal.NewFromString("136.02")
	if err != nil {
		panic(err)
	}

	var quantity decimal.Decimal = 3

	fee := decimal.NewFromFloat(.035)
	taxRate, _ := decimal.NewFromString(".08875")

	subtotal := price.Mul(quantity)

	preTax := subtotal.Mul(fee.Add(1))

	total := preTax.Mul(taxRate.Add(1))

	fmt.Println("Subtotal:", subtotal)                      // Subtotal: 408.06
	fmt.Println("Pre-tax:", preTax)                         // Pre-tax: 422.3421
	fmt.Println("Taxes:", total.Sub(preTax))                // Taxes: 37.482861375
	fmt.Println("Total:", total)                            // Total: 459.824961375
	fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875
}

Weight and Length

Weight and Length are companion fixed-point types with the same 8-byte layout as Decimal but with 4 bits reserved for a unit code (53-bit mantissa instead of 57).

w1, _ := decimal.NewWeightFromString("123.45kg")
w2, _ := decimal.NewWeightFromString("550g")
fmt.Println(w1.Add(w2)) // 124kg
fmt.Println(w2.Add(w1)) // 124000g — w2 unit (g) is preserved

Weight units: SI multiples of kg (t, kt, Mt, Gt, g, mg, µg, ng, pg) plus avoirdupois and troy (lb, oz, lb t, oz t, with mcg/lb av/oz av aliases).

l1, _ := decimal.NewLengthFromString("1ft")
l2, _ := decimal.NewLengthFromString("12in")
fmt.Println(l1.Add(l2)) // 2ft (NIST 1959: 1 ft = 12 in exact)
fmt.Println(decimal.NewLengthFromString("1au")) // 149597870700m (UAI 2012)

Length units: m, km, dm, cm, mm, µm (alias um), nm, pm, au (alias ua), in, ft, yd, mi.

shopspring/decimal compatibility

The public API mirrors shopspring/decimal. Methods added for compatibility include DivRound, PowInt32, Shift, Truncate, RoundUp, RoundDown, RoundCash, StringFixedCash, NumDigits, Copy, Normalize (a no-op: the representation is already unique) and NewFromFormattedString. Decimal implements fmt.Formatter like shopspring v1.6: %.2f rounds like StringFixed, with width and the -, +, and 0 flags, %d prints integer decimals and %#v prints Go syntax such as decimal.New(-314, -2). JSON output is unquoted by default (raw number) — incompatible with shopspring's quoted-string default; route values through MarshalText / UnmarshalText if you need cross-package interop.

Rounding matches shopspring on every entry point (Round, StringFixed, DivRound, RoundCash, RoundBank, RoundUp/Down/Ceil/Floor, Truncate), checked value by value against shopspring v1.4.0 and v1.6.0 by bench/compare_round_test.go: a half rounds away from zero, symmetrically, so -2.5 rounds to -3 and a credit note rounds like its invoice. Up to v1.0.2 a negative half rounded toward +∞ (-2.5 → -2). Since v1.1.0, Truncate with a negative precision truncates the integer part like shopspring v1.5+ (5432 → 5400 at -2; shopspring v1.4 and aytechnet v1.0.2 returned the value unchanged).

NewFromFloat and NewFromFloat32 follow shopspring since v1.1.0: they convert the shortest decimal that gives the same float back (strconv.FormatFloat(f, 'g', -1, 64)), so NewFromFloat(-178464.49) is exactly -178464.49. Up to v1.0.2 they converted the binary value with a precision bug from the 16th digit (~-178464.49000000009, 97 % of 2-3 decimal amounts differed). Checked against shopspring on 1,000,000 random floats by bench/compare_round_test.go; a value with more than 16 fractional digits is rounded to the 16 a Decimal holds (loss bit set). NewFromFloat64Exact still converts the binary value (correctly rounded to the mantissa since v1.1.0, ~-178464.48999999999): the math functions use it.

NewFromFloatWithExponent(value, exp) follows shopspring since v1.1.0: exp is an exponent (-2 keeps 2 decimal places; up to v1.0.2 it was a number of places, 2), and the exact binary value of the float is rounded half away from zero, so NewFromFloatWithExponent(0.015, -2) is 0.01 (0.015 is 0.01499999… as a float64). It is checked against shopspring v1.4.0 and v1.6.0 on 200,000 random floats by bench/compare_round_test.go, to within one unit of the 17th significant digit. Unlike shopspring it returns NaN/±Inf instead of panicking.

Ln signature is intentionally NOT compatible

shopspring returns Ln(precision int32) (Decimal, error); this package returns Ln(precision int32) Decimal — no error. This is a deliberate design choice, not an oversight. Because the type natively supports NaN and ±Inf (every special value is a real, propagating member of the set), an out-of-domain input simply yields a NaN/-Inf result instead of an error:

// aytechnet: chains naturally, NaN propagates if d <= 0
result := d.Ln(16).Add(k).Mul(rate)

// shopspring: the (Decimal, error) return breaks the expression
l, err := d.Ln(16)
if err != nil { /* handle */ }
result := l.Add(k).Mul(rate)

The same rationale applies to the other float-backed transcendental/trig methods (Sqrt, Sin, Cos, Tan, Atan, Pow): they never return an error, so they compose inside a single expression. Check IsNaN() / IsInfinite() on the final value when the domain is uncertain, exactly as you would inspect a float64 result. If you need shopspring's error-returning shape, wrap the call: func ln(d Decimal) (Decimal, error) { r := d.Ln(16); if r.IsNaN() { return r, errLn }; return r, nil }.

Sqrt, SqrtRound, Root and RootRound signatures are intentionally NOT compatible

shopspring v1.6.0 added Sqrt() (Decimal, error), SqrtRound(places int32) (Decimal, error), Root(n int64) (Decimal, error) and RootRound(n int64, places int32) (Decimal, error). This package keeps its existing Sqrt() Decimal, on purpose and for the same reason as Ln: changing it would break every caller of the v1 API, and a negative input already yields NaN instead of an error, so the call composes in an expression. SqrtRound(places int32) Decimal, Root(n int64) Decimal and RootRound(n int64, places int32) Decimal follow the same rule: no error, NaN for n < 1 or an even root of a negative number. They are computed from float64 (~16 significant digits, exact integer roots such as Root(32, 5) = 2 stay exact), where shopspring computes DivisionPrecision places exactly with big.Int. Code written for shopspring's versions therefore does not compile against this package as is; drop the error, or wrap the call as shown for Ln above.

Methods around math/big (NewFromBigInt, NewFromBigRat, BigInt, BigFloat, Rat, Coefficient) are not supported by design — the whole point of the package is to avoid big.Int allocations.

Benchmarks

All figures: vs shopspring/decimal v1.6.0, Ryzen 5 8540U, Go 1.26, -count=6 -benchtime=100ms averaged. aytechnet is allocation-free on every operation below. shopspring v1.5/v1.6 roughly halved its own costs (fewer big.Int allocations, faster Ln, NewFromFloat and trig), so the gaps are narrower than with v1.4.0; aytechnet's own timings are unchanged.

Synthesis (speedup ranges by category)
Category Speedup range aytechnet allocs Notes
Fractional arithmetic (Add/Mul/Div/Pow) 4×–19× 0 Div 19×, Mul 4×
Conversion (NewFromString/Float/String) 1.3×–2× 0–1 shortest-decimal NewFromFloat 1.3×
Pure-integer arithmetic 11×–26× 0 shopspring allocates big.Int
Integer construction (NewFromInt/Int32) 17×–~50× 0 Int32 near measurement floor
Running sum Σ i (convert + add) ~19× 0 true data dependency, most defensible
Transcendental / trig (Sin/Cos/Tan/Atan/Ln) ~40×–~95× 0 NOT iso-precision — see caveat below
Sqrt / Root ~15× / ~31× 0 close to iso-precision (16 places both)

Detailed per-operation tables follow.

Comparison against shopspring/decimal v1.6.0 on a Ryzen 5 8540U (Go 1.26, 6 runs averaged):

Operation aytechnet shopspring Speedup aytechnet allocs shopspring allocs
Add 9.4 ns/op 57 ns/op 6× 0 2 (80 B)
Mul 10.2 ns/op 44 ns/op 4× 0 2 (80 B)
Div 8.3 ns/op 161 ns/op 19× 0 8 (232 B)
Pow(1.1, 60) 39 ns/op 217 ns/op 6× 0 7 (224 B)
NewFromString 37 ns/op 81 ns/op 2× 0 2 (40 B)
NewFromFloat 52 ns/op 65 ns/op 1.3× 0 2 (40 B)
String 54 ns/op 106 ns/op 2× 1 (24 B) 2 (32 B)

Reproduce: cd bench && go test -bench=. -benchmem. The bench/ sub-module has its own go.mod so the main package keeps zero external dependencies.

Pure integers

On operands with no fractional part — counts, quantities, integer money in minor units — aytechnet/decimal stays pure int64 arithmetic with zero allocations, while shopspring/decimal still goes through math/big. Ryzen 5 8540U, Go 1.26, 6 runs averaged (every benchmark writes its result to a sink and derives constructor inputs from the loop index, so the compiler cannot eliminate or constant-fold the call):

Operation aytechnet shopspring Speedup aytechnet allocs shopspring allocs
Add (int) 1.7 ns/op 44 ns/op 26× 0 2 (80 B)
Sub (int) 1.7 ns/op 35 ns/op 21× 0 2 (40 B)
Mul (int) 2.2 ns/op 47 ns/op 21× 0 2 (80 B)
Div (exact, 620/31) 7.5 ns/op 93 ns/op 12× 0 4 (120 B)
Div (inexact, 1e15/7) 14 ns/op 149 ns/op 11× 0 7 (224 B)
NewFromInt 1.3 ns/op 23 ns/op 17× 0 2 (40 B)
NewFromInt32 0.4 ns/op 22 ns/op ~50× † 0 2 (40 B)

† NewFromInt32 inlines to little more than a sign-extension, because an in-range integer is the internal encoding (type Decimal int64); at ~1 CPU cycle this figure sits near the measurement floor and is inlining-sensitive — the arithmetic core's honest range is ~11–26× (division ~11–12×, add/sub/mul ~21–26×).

The most representative figure is a running sum (acc = 0 + 1 + 2 + …, one int→Decimal conversion plus one Add per term, accumulator carried across iterations so the work is a genuine data dependency — no compiler trickery possible): 2.4 ns/term, 0 allocations vs 46 ns/term, 2 allocations for shopspring (~19×). This mirrors summing a column of integer amounts on an invoice. Note: the running total stays exact only while it fits aytechnet's 57-bit mantissa (sum ≈ b.N²/2 < 1.44e17, i.e. b.N < ~5.4e8, which covers the default -benchtime=1s); past that the per-term cost rises to ~6 ns as adds take the rounding path, so pin a short -benchtime (or -benchtime=300000000x) for the headline figure.

Reproduce: cd bench && go test -bench='Int|Sum' -benchmem -count=6 -benchtime=200ms.

Transcendental / trigonometric

Ln, Sin, Cos, Tan, Atan and Sqrt (added to shopspring in v1.6.0) are iterative functions, not hot-path. These figures are indicative, not iso-precision: aytechnet computes to its ~17-digit int64 mantissa, while shopspring computes to a higher internal precision with math/big — so part of the gap is aytechnet doing less work. aytechnet stays allocation-free throughout; correctness is checked against the stdlib math package in TestMathAccuracy (all within 1e-13).

Operation aytechnet shopspring Speedup aytechnet allocs shopspring allocs
Sin(0.5) 38 ns/op 3382 ns/op ~88× 0 71 (4920 B)
Cos(0.5) 40 ns/op 3760 ns/op ~94× 0 77 (5448 B)
Tan(0.5) 38 ns/op 2731 ns/op ~71× 0 62 (3954 B)
Atan(0.5) 34 ns/op 1469 ns/op ~43× 0 51 (2136 B)
Ln(2.5) (precision 16) 57 ns/op 2541 ns/op ~45× 0 51 (2288 B)
Sqrt(2) 23 ns/op 336 ns/op ~15× 0 11 (248 B)
Root(2, 3) 51 ns/op 1567 ns/op ~31× 0 39 (1296 B)

These large multipliers are dominated by the precision mismatch: aytechnet's trig are backed by hardware float64 (≈15–16 significant digits, the most this 17-digit type can hold) and round once, whereas shopspring computes to arbitrary precision with math/big (e.g. Ln does 51 allocations / 2.3 kB). The honest reading is "if 16 digits is enough, aytechnet gives it allocation-free for one to two orders of magnitude less work" — not that the algorithms are intrinsically 40×–95× better.

Ln (precision >= 16) is special: it does not use float64/math.Log. It reduces the value in binary to a·2^K, a ∈ [1,2), and sums the atanh series ln(a) = 2(s + s³/3 + …) in a 2^63-scaled fixed point (the full 64-bit mantissa). This fills the type's 57-bit precision — verified against an independent 240-bit big.Float reference (TestLnHighPrecision) to < 1e-16 relative, typically ~1e-17, i.e. ~10× tighter than the float64 path. The right way to read its speed: getting that 17th correct digit any other way means an arbitrary-precision library (math/big), which is ~2.5 µs here with shopspring v1.6 — so this path is both more precise and ~45× faster than the only alternative that matches its precision. The ~4 ns it costs over aytechnet's own float64 path is noise by comparison, and it means you never have to recompute in a slower big-number library for the extra digit. Values whose result |ln| is tiny (x within ~1 % of 1) fall back to the float64 path: there the 2^63 fixed-point scale loses relative precision and math.Log is more accurate. Any precision < 16 call also takes the plain float64 path. (A dedicated 128-bit near-1 variant was prototyped to cover that band at full precision but did not reach the required accuracy in testing, so it was dropped in favour of the float64 fallback.)

Reproduce: cd bench && go test -bench='Ln|Sin|Cos|Tan|Atan|Sqrt' -benchmem -count=6 -benchtime=100ms.

Why this package

This package has been created in 2022 and has been used internally for e-commerce related softwares at Aytechnet like DyaPi or Velonomad. At this time, almost only shopspring/decimal was available. I would like a decimal package with omitempty friendly interface to encoding/json and a small memory usage.

Since then, much more decimal package alternatives have been made available.

License

The MIT License (MIT)

Some portion of this code inspired directly from shopspring/decimal, which is also released under the MIT Licence.

Documentation

Overview

Package decimal provides a high-performance, zero-allocation fixed-point decimal type (and companion Weight / Length types with unit support) packed in a single 8-byte int64. See README.md for an overview and BINARY_FORMAT.md for the open wire-format specification.

Index

Constants

View Source
const (
	// LengthMaxInt constant is the maximal int64 value that can be safely saved as Length with exponent still 0.
	// LengthMaxInt is as well the maximum value of mantissa of Length and the bitmask to extract mantissa value of a Length.
	LengthMaxInt = 0x001fffffffffffff
)
View Source
const (
	// WeightMaxInt constant is the maximal int64 value that can be safely saved as Weight with exponent still 0.
	// WeightMaxInt is as well the maximum value of mantissa of Weight and the bitmask to extract mantissa value of a Weight.
	WeightMaxInt = 0x001fffffffffffff
)

Variables

View Source
var (
	// ErrOutOfRange can occurs when converting a decimal to a int or int64 as integer may not hold the integer part of the decimal value.
	ErrOutOfRange = errors.New("out of range")

	// ErrSyntax can occurs when converting a string to a decimal.
	ErrSyntax = errors.New("invalid syntax")

	// ErrUnitSyntax occurs when unit is not recognized.
	ErrUnitSyntax = errors.New("invalid unit syntax")

	// ErrFormatcan occurs when decoding a binary to a decimal.
	ErrFormat = errors.New("invalid format")

	// DivisionPrecision has the number of decimal places in the result when it doesn't divide exactly.
	DivisionPrecision = 16

	// PowPrecisionNegativeExponent has the maximum precision (digits after the decimal point) of the result of PowInt32 when the exponent is negative.
	PowPrecisionNegativeExponent = 16
)

Functions

This section is empty.

Types

type Decimal

type Decimal int64

Decimal represents a fixed-point decimal hold as a 64 bits integer integer value between -144115188075855871 and 144115188075855871 (or MaxInt) can safely be used as Decimal, example :

var a Decimal = -1001 // a is a Decimal of integer value -1001

if a.Div(1000).Sub(1).Div(5).Mul(14000).Add(14).Div(-28) == 1000 {
  fmt.Printf("ok: (((a/1000)-1)*14000+14)/-28 == 1000\n") // will print "ok: (((a/1000)-1)*14000+14)/-28 == 1000"
}

Note 0 is unitialized Decimal and its value for calculation is 0 like Zero which is initialized 0 Note Zero is now the same int64 value as types.IntZero, so casting an types.IntZero to Decimal is safe provided is absolute value is not too high Note you need to use Decimal method for calculation, you cannot use + - * / or any other operators unless Decimal is a real non-zero integer value Unitialized Decimal is useful when using JSON marshaling/unmarshaling.

Note Decimal does not follow IEEE 754 decimal floating point 64 bits representation. This is because Decimal is compatible with a large range of int64 values as described above for ease of use and use extended mantissa of 57 bits instead of 50 bits for IEEE 754 decimal floating point, thus providing only 17 significant digits (in fact a little more than float64)

const (
	// Null constant is the default value of a decimal left unitialized.
	// A decimal can be directly initialized with 0 and it will be empty.
	// Null can be safely compared with == or != directly, you may use decimal.IsNull or any other decimal method to check if it is null.
	// Any operation on Decimal will never return a Null.
	// Null is seen as 0 for any operation
	Null = 0

	// MaxInt constant is the maximal int64 value that can be safely saved as Decimal with exponent still 0.
	// MaxInt is as well the maximum value of mantissa of Decimal and the bitmask to extract mantissa value of a Decimal.
	MaxInt = 0x01ffffffffffffff

	// Zero constant is not empty zero Decimal value.
	// A decimal can be directly initialized with Zero and it will be not empty, but zero.
	// Zero can be safely compared with == or != directly to check for not empty zero decimal value.
	// But you need to use d.IsExactlyZero() to test if decimal d is zero or null.
	Zero Decimal = math.MinInt64

	// NearZero represents a decimal value too close to 0 but not equal to zero, its sign is undefined.
	// NearPositiveZero and NearNegativeZero represents a signed decimal value too close to 0 but not equal to zero, its sign has been kept.
	// They can be safely compared with == or != directly but -NearZero may occurs and should be "seen" as NearZero
	NearZero         Decimal = Zero | loss
	NearPositiveZero Decimal = 0x6000000000000000
	NearNegativeZero Decimal = -NearPositiveZero

	// PositiveInfinity and NegativeInfinity are constants that represents decimal too big to be represented as a decimal value.
	// They can safely be compared with == or != directly to check for infinite value.
	PositiveInfinity Decimal = 0x5e00000000000000
	NegativeInfinity Decimal = -PositiveInfinity

	// NaN represent a decimal which do not represents any more a number.
	// NaN should never be compared with == or != directly as they are multiple representation of such "nan" internally (search for NaN boxing for more info).
	// Use IsNaN method to check if a decimal is not a number.
	NaN Decimal = 0x4200000000000000
)

func Avg

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

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

func Max

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

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

func Min

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

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

func New

func New(value int64, exp int32) Decimal

New returns a new fixed-point decimal, value * 10 ^ exp, compatible with shopspring/decimal New function.

func NewFromBytes

func NewFromBytes(value []byte) (Decimal, error)

NewFromBytes returns a new Decimal from a slice of bytes representation.

func NewFromFloat

func NewFromFloat(value float64) Decimal

NewFromFloat converts a float64 to Decimal using the shortest decimal that converts back to the same float64, like shopspring/decimal and strconv.FormatFloat(value, 'g', -1, 64): NewFromFloat(-178464.49) is exactly -178464.49, not the binary value -178464.48999999999068... It has at most 17 significant digits, so it always fits the 57-bit mantissa and is exact (no loss bit). -0 gives NearNegativeZero, NaN and ±Inf give NaN and ±Inf.

NewFromFloat64Exact converts the binary value instead, as the math functions do.

func NewFromFloat32

func NewFromFloat32(value float32) Decimal

NewFromFloat32 converts a float32 to Decimal using the shortest decimal that converts back to the same float32, like shopspring/decimal: NewFromFloat32(54.33) is exactly 54.33.

func NewFromFloat64Exact

func NewFromFloat64Exact(value float64, exact bool) Decimal

NewFromFloat64Exact converts the binary value of a float64 to Decimal, rounded to the 57-bit mantissa with the loss bit set when rounded (0.1 is ~0.1000000000000000055…); when exact is false, the loss bit is forced on the result. The math functions (Sqrt, Sin, Atan…) use it. NewFromFloat converts the shortest decimal instead, which is what a float literal or a parsed amount means.

func NewFromFloatWithExponent

func NewFromFloatWithExponent(value float64, exp int32) Decimal

NewFromFloatWithExponent converts a float64 to Decimal with -exp fractional digits, like shopspring/decimal: exp is an exponent, so -2 keeps 2 decimal places and 1 rounds to the tens. The exact binary value of the float is rounded half away from zero, so 0.015, which is 0.01499999999999999944... as a float64, gives 0.01 at exp -2 (NewFromFloat(0.015).Round(2) gives 0.02). Unlike shopspring it does not panic on NaN or ±Inf, it returns them.

Example:

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

func NewFromFormattedString added in v1.0.0

func NewFromFormattedString(value string, replRegexp *regexp.Regexp) (Decimal, error)

NewFromFormattedString returns a new Decimal from a formatted string representation. Characters matching replRegexp are stripped from value before parsing.

Useful to consume locale-formatted numbers, e.g. "$1,234.56" or " 9 876.54 €":

r := regexp.MustCompile(`[$,€\s]`)
d, err := NewFromFormattedString("$1,234.56", r) // d = 1234.56

Note: the function only removes characters; if you need to swap a comma decimal separator for a dot, preprocess value yourself before calling.

func NewFromInt

func NewFromInt(value int64) Decimal

NewFromInt converts a int64 to Decimal.

func NewFromInt32

func NewFromInt32(value int32) Decimal

NewFromInt32 converts a int32 to Decimal.

func NewFromString

func NewFromString(value string) (Decimal, error)

NewFromString returns a new Decimal from a string representation.

Example:

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

func NewFromUint64

func NewFromUint64(value uint64) Decimal

NewFromUint64 converts uint64 to Decimal.

func RequireFromString

func RequireFromString(value string) Decimal

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

Example:

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

func Sum

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

Sum returns the combined total of the provided first and rest Decimals using improved Kahan–Babuška Neumaier algorithm, see https://en.wikipedia.org/wiki/Kahan_summation_algorithm

Example:

d := Sum(1, RequireFromString("1e30"), 1, RequireFromString("-1e30"))

func (Decimal) Abs

func (d Decimal) Abs() Decimal

Abs returns the absolute value of the decimal.

func (Decimal) Add

func (d1 Decimal) Add(d2 Decimal) Decimal

Add returns d1 + d2.

func (Decimal) Atan

func (d Decimal) Atan() Decimal

Atan returns the arctangent, in radians, of d.

func (Decimal) BytesTo added in v0.5.0

func (d Decimal) BytesTo(b []byte) []byte

BytesTo appends the string representation of the decimal to a slice of byte, if the decimal is Null it appends 0.

func (Decimal) BytesToFixed added in v0.5.0

func (d Decimal) BytesToFixed(b []byte, places int32) []byte

func (Decimal) BytesToFixedBank added in v0.5.0

func (d Decimal) BytesToFixedBank(b []byte, places int32) []byte

func (Decimal) Ceil

func (d Decimal) Ceil() Decimal

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

func (Decimal) Cmp

func (d1 Decimal) Cmp(d2 Decimal) int

Cmp is a synonym of Compare.

func (Decimal) Compare

func (d1 Decimal) Compare(d2 Decimal) int

Compare compares the numbers represented by d1 and d2 without taking into account lost precision and returns:

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

func (Decimal) Copy added in v0.6.0

func (d Decimal) Copy() Decimal

Copy returns a copy of the decimal. As Decimal is an immutable int64, the returned value has the same bit pattern. Provided for API compatibility with shopspring/decimal.

func (Decimal) Cos

func (d Decimal) Cos() Decimal

Cos returns the cosine of the radian argument d.

func (Decimal) Div

func (d1 Decimal) Div(d2 Decimal) Decimal

Div returns d1 / d2. If it doesn't divide exactly, the result will have DivisionPrecision digits after the decimal point and loss bit will be set.

func (Decimal) DivRound added in v0.6.0

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

DivRound divides d1 by d2 and rounds the result to a given precision (an integer multiple of 10^(-precision)).

Rounding follows the package Round semantics. Negative precision is allowed.

func (Decimal) Equal

func (d1 Decimal) Equal(d2 Decimal) bool

Equal returns whether d1 == d2 without taking care of loss bit. The values Null, Zero, NearZero, NearPositiveZero and NearNegativeZero are equals.

func (Decimal) Exponent added in v0.0.5

func (d Decimal) Exponent() int32

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

func (Decimal) Float64

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

Float64 returns the nearest float64 value for d and a bool indicating whether f may represents d exactly.

func (Decimal) Floor

func (d Decimal) Floor() Decimal

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

func (Decimal) Format added in v1.1.0

func (d Decimal) Format(f fmt.State, verb rune)

Format implements fmt.Formatter, so decimals work with the fmt verbs like shopspring/decimal:

  • %v and %s print String(), and %q, %x and %X quote it or print it in hex, as for any fmt.Stringer.
  • %f and %F print fixed-point notation. With a precision, as in %.2f, the decimal is rounded like StringFixed. Without one, it is printed like String(). Width and the '-', '+', ' ' and '0' flags work as they do for floats.
  • %d prints an integer decimal as an int64 (Null and Zero print 0); a fractional or special decimal prints fmt's usual error, such as %!d(decimal.Decimal=3.14).
  • %#v prints Go syntax that recreates the decimal exactly: decimal.New(-314, -2) for an exact finite value, the constant name for Null, Zero, NaN, ±Inf and the near zeros, and decimal.Decimal(<int64>) for an inexact value (loss bit set).

Other verbs print fmt's usual error.

func (*Decimal) GobDecode

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

GobDecode implements the gob.GobDecoder interface for gob serialization.

func (Decimal) GobEncode

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

GobEncode implements the gob.GobEncoder interface for gob serialization.

func (Decimal) GreaterThan added in v0.3.0

func (d1 Decimal) GreaterThan(d2 Decimal) bool

GreaterThan returns true when d1 is greater than d2 (d1 > d2).

func (Decimal) GreaterThanOrEqual added in v0.3.0

func (d1 Decimal) GreaterThanOrEqual(d2 Decimal) bool

GreaterThanOrEqual returns true when d1 is greater than or equal to d2 (d1 >= d2).

func (Decimal) IfNull

func (d Decimal) IfNull(defaultValue Decimal) Decimal

IfNull return

default_value if d == Null
d in any other cases

func (Decimal) InexactFloat64

func (d Decimal) InexactFloat64() float64

InexactFloat64 returns the nearest float64 value for d.

func (Decimal) Int64

func (d Decimal) Int64() (i int64)

Int64 returns the integer component of the decimal, this method is a synonym of IntPart

func (Decimal) IntPart

func (d Decimal) IntPart() (i int64)

IntPart returns the integer component of the decimal.

func (Decimal) IntPartErr

func (d Decimal) IntPartErr() (int64, error)

IntPartErr return the integer component of the decimal and an eventual out-of-range error of conversion.

func (Decimal) IsExact

func (d Decimal) IsExact() bool

IsExact return true if a decimal has its loss bit not set, ie it has not lost its precision during computation or conversion.

func (Decimal) IsExactlyZero

func (d Decimal) IsExactlyZero() bool

IsExactlyZero return

true if d == Null or d == Zero
false if d == ~0 or d == -~0 or d == +~0
false if d < 0
false if d > 0

func (Decimal) IsInfinite

func (d Decimal) IsInfinite() bool

IsInfinite return

true if a d == +Inf or d == -Inf
false in any other case

func (Decimal) IsInteger

func (d Decimal) IsInteger() bool

IsInteger return true only if d is zero or can be safely casted as int64

func (Decimal) IsNaN

func (d Decimal) IsNaN() bool

IsNaN return

true if d is not a a number (NaN)
false in any other case

func (Decimal) IsNegative

func (d Decimal) IsNegative() bool

IsNegative return

true if d < 0 or d == ~-0
false if d == Null or d == Zero or d == ~0
false if d > 0

func (Decimal) IsNull

func (d Decimal) IsNull() bool

IsNull return

true if d == Null
false if d == 0
false if d == ~0 or d == -~0 or d == +~0
false if d < 0
false if d > 0

func (Decimal) IsPositive

func (d Decimal) IsPositive() bool

IsPositive return

true if d > 0 or d == ~+0
false if d == Null or d == Zero or d == ~0
false if d < 0 or d == ~-0
false if d is NaN

func (Decimal) IsSet

func (d Decimal) IsSet() bool

IsSet return

false if d == Null
true if d == 0
true if d == ~0 or d == -~0 or d == +~0
true if d < 0
true if d > 0

func (Decimal) IsZero

func (d Decimal) IsZero() bool

IsZero return

true if d == Null or d == Zero
true if d == ~0 or d == -~0 or d == +~0
false if d < 0
false if d > 0

func (Decimal) LessThan

func (d1 Decimal) LessThan(d2 Decimal) bool

LessThan returns true when d1 is less than d2 (d1 < d2).

func (Decimal) LessThanOrEqual

func (d1 Decimal) LessThanOrEqual(d2 Decimal) bool

LessThanOrEqual returns true when d1 is less than or equal to d2 (d1 <= d2).

func (Decimal) Ln

func (d Decimal) Ln(precision int32) Decimal

Ln calculates natural logarithm of d. Precision argument specifies how precise the result must be (number of digits after decimal point). Negative precision is allowed.

For precision >= 16 and a normal strictly-positive finite operand, Ln uses a fixed-point binary-reduction + atanh-series path (ln_highprec.go) that fills the type's full 57-bit mantissa, avoiding math.Log entirely. It is ~10× more accurate at the last digit than the float64 path; getting that precision any other way needs an arbitrary-precision library (~1200× slower), so the few ns it costs over the float64 path is negligible. Values whose result |ln| is tiny (x within ~1% of 1) fall back to the float64 path, which math.Log computes accurately in that regime; any precision < 16 call also uses the float64 path. NaN for d <= 0.

func (Decimal) Mantissa added in v0.0.5

func (d Decimal) Mantissa() int64

Mantissa returns the mantissa of the decimal.

func (Decimal) MarshalBinary

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

MarshalBinary implements the encoding.BinaryMarshaler interface.

func (Decimal) MarshalJSON

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

MarshalJSON implements the json.Marshaler interface.

func (Decimal) MarshalText

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

MarshalText implements the encoding.TextMarshaler interface for XML serialization.

func (Decimal) Mod

func (d1 Decimal) Mod(d2 Decimal) Decimal

Mod returns d1 % d2.

func (Decimal) Mul

func (d1 Decimal) Mul(d2 Decimal) Decimal

Mul returns d1 * d2.

func (Decimal) Neg

func (d Decimal) Neg() Decimal

Neg returns -d.

func (Decimal) Normalize added in v1.1.0

func (d Decimal) Normalize() Decimal

Normalize returns d unchanged: a Decimal already has a unique representation (1.50, 1.5 and New(15, -1) are the same int64, and every exact zero is Zero), so == and reflect.DeepEqual compare values. Provided for API compatibility with shopspring/decimal, where it strips the trailing zeros of the coefficient.

func (Decimal) NumDigits added in v0.6.0

func (d Decimal) NumDigits() int

NumDigits returns the number of digits of the decimal mantissa in base 10. Mantissa is only normalized (trailing zeros dropped) when its absolute value would otherwise exceed MaxInt or its exponent would be out of range, so 100 is kept as mantissa=100 (NumDigits=3) while 10^18 is normalized to mantissa=1, exp=18 (NumDigits=1). Null, Zero, NearZero, NearPositiveZero, NearNegativeZero, +Inf, -Inf and NaN return 1.

func (Decimal) Pow

func (d1 Decimal) Pow(d2 Decimal) Decimal

Pow returns d1**d2, the base-d1 exponential of d2.

func (Decimal) PowInt32 added in v0.6.0

func (d Decimal) PowInt32(exp int32) (Decimal, error)

PowInt32 returns d to the power of exp using fast exponentiation by squaring (so without going through float64 like Pow). When exp is negative, the result is rounded to PowPrecisionNegativeExponent digits after the decimal point.

Returns an error only when d is zero and exp is zero (indeterminate form 0**0).

Examples:

NewFromFloat(4).PowInt32(4)    // 256, nil
NewFromFloat(3.13).PowInt32(5) // 300.4150512793, nil
NewFromFloat(15.2).PowInt32(-2) // 0.0043282548476454, nil

func (Decimal) PowWithPrecision

func (d1 Decimal) PowWithPrecision(d2 Decimal, precision int32) (Decimal, error)

PowWithPrecision returns d to the power of d2. Precision parameter specifies minimum precision of the result (digits after decimal point). Returned decimal is not rounded to 'precision' places after decimal point.

func (Decimal) QuoRem

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

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

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

Note that precision<0 is allowed as input.

func (Decimal) Root added in v1.1.0

func (d Decimal) Root(n int64) Decimal

Root returns the n-th root of d. Odd roots of negative numbers are negative.

Special cases are:

Root(n < 1) = NaN
Root(x < 0) = NaN for an even n
Root(±0) = ±0
Root(+Inf) = +Inf, Root(-Inf) = -Inf for an odd n
Root(NaN) = NaN

Intentionally NOT compatible with shopspring/decimal v1.6+, whose Root returns (Decimal, error): an out-of-domain input yields NaN instead of an error, and the result has the precision of a float64 (~16 significant digits) rather than DivisionPrecision places (see README).

func (Decimal) RootRound added in v1.1.0

func (d Decimal) RootRound(n int64, places int32) Decimal

RootRound returns the n-th root of d rounded half away from zero to places digits after the decimal point, like Round. Same special cases and float64 precision as Root.

Intentionally NOT compatible with shopspring/decimal v1.6+, whose RootRound returns (Decimal, error).

func (Decimal) Round

func (d Decimal) Round(places int32) Decimal

Round rounds the decimal to places decimal places. If places < 0, it will round the integer part to the nearest 10^(-places). A half rounds away from zero, like shopspring/decimal: 2.5 -> 3 and -2.5 -> -3.

func (Decimal) RoundBank

func (d Decimal) RoundBank(places int32) Decimal

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

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

Examples:

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

func (Decimal) RoundCash added in v0.6.0

func (d Decimal) RoundCash(interval uint8) Decimal

RoundCash rounds the decimal to the nearest multiple of the given Cash interval (in units of 10^(-2), or hundredths). Valid intervals are 5, 10, 25, 50 and 100 (Swedish/cash rounding). Panics for any other interval.

Examples:

NewFromFloat(3.43).RoundCash(5)   // 3.45
NewFromFloat(3.45).RoundCash(10)  // 3.5
NewFromFloat(3.41).RoundCash(25)  // 3.5
NewFromFloat(3.75).RoundCash(50)  // 4
NewFromFloat(3.50).RoundCash(100) // 4

func (Decimal) RoundCeil

func (d Decimal) RoundCeil(places int32) Decimal

RoundCeil rounds the decimal towards +infinity.

func (Decimal) RoundDown added in v0.6.0

func (d Decimal) RoundDown(places int32) Decimal

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

Examples:

NewFromFloat(545).RoundDown(-2).String()    // "500"
NewFromFloat(-500).RoundDown(-2).String()   // "-500"
NewFromFloat(1.1001).RoundDown(2).String()  // "1.1"
NewFromFloat(-1.454).RoundDown(1).String()  // "-1.4"

func (Decimal) RoundFloor

func (d Decimal) RoundFloor(places int32) Decimal

RoundFloor rounds the decimal towards -infinity.

Example:

NewFromFloat(545).RoundFloor(-2).String()   // output: "500"
NewFromFloat(-500).RoundFloor(-2).String()   // output: "-500"
NewFromFloat(1.1001).RoundFloor(2).String() // output: "1.1"
NewFromFloat(-1.454).RoundFloor(1).String() // output: "-1.5"

func (Decimal) RoundUp added in v0.6.0

func (d Decimal) RoundUp(places int32) Decimal

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

Examples:

NewFromFloat(545).RoundUp(-2).String()    // "600"
NewFromFloat(500).RoundUp(-2).String()    // "500"
NewFromFloat(1.1001).RoundUp(2).String()  // "1.11"
NewFromFloat(-1.454).RoundUp(1).String()  // "-1.5"

func (*Decimal) Scan

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

Scan implements the sql.Scanner interface for database deserialization.

func (Decimal) Shift added in v0.6.0

func (d Decimal) Shift(shift int32) Decimal

Shift shifts the decimal in base 10. Positive shift moves left (multiply by 10^shift), negative shift moves right. In other words, the value of shift is added to the exponent of the decimal.

Examples:

d, _ := NewFromString("123.45")
d.Shift(1).String()   // "1234.5"
d.Shift(-1).String()  // "12.345"

func (Decimal) Sign

func (d Decimal) Sign() int

Sign return

0 if d == Null or d == Zero or d == ~0
1 if d > 0 or d == ~+0
-1 if d < 0 or d == ~-0
undefined (1 or -1) if d is NaN

func (Decimal) Sin

func (d Decimal) Sin() Decimal

Sin returns the sine of the radian argument d.

func (Decimal) Sqrt

func (d Decimal) Sqrt() Decimal

Sqrt computes the (possibly rounded) square root of a decimal.

Special cases are:

Sqrt(+Inf) = +Inf
Sqrt(±0) = ±0
Sqrt(x < 0) = NaN
Sqrt(NaN) = NaN

Intentionally NOT compatible with shopspring/decimal v1.6+, whose Sqrt returns (Decimal, error): the existing v1 signature is kept, a negative input yields NaN instead of an error (see README).

func (Decimal) SqrtRound added in v1.1.0

func (d Decimal) SqrtRound(places int32) Decimal

SqrtRound returns the square root of d rounded half away from zero to places digits after the decimal point, like Round. It is computed from float64, so beyond ~16 significant digits the digits are those of Sqrt.

Intentionally NOT compatible with shopspring/decimal v1.6+, whose SqrtRound returns (Decimal, error): a negative input yields NaN instead of an error (see README).

func (Decimal) String

func (d Decimal) String() string

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

Example:

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

Output:

-12.345

func (Decimal) StringFixed added in v0.3.0

func (d Decimal) StringFixed(places int32) string

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

Example:

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

func (Decimal) StringFixedBank added in v0.3.0

func (d Decimal) StringFixedBank(places int32) string

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

Example:

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

func (Decimal) StringFixedCash added in v0.6.0

func (d Decimal) StringFixedCash(interval uint8) string

StringFixedCash returns a Cash-rounded fixed-point string with 2 digits after the decimal point. See RoundCash for the interval semantics.

Examples:

NewFromFloat(3.43).StringFixedCash(5)   // "3.45"
NewFromFloat(3.75).StringFixedCash(50)  // "4.00"

func (Decimal) Sub

func (d1 Decimal) Sub(d2 Decimal) Decimal

Sub returns d1 - d2.

func (Decimal) Tan

func (d Decimal) Tan() Decimal

Tan returns the tangent of the radian argument x.

func (Decimal) Truncate added in v0.6.0

func (d Decimal) Truncate(precision int32) Decimal

Truncate truncates digits from the decimal without rounding (towards zero), keeping precision digits after the decimal point. A negative precision truncates the integer part, like shopspring/decimal v1.5+.

Example:

d, _ := NewFromString("123.456")
d.Truncate(2).String()  // "123.45"
New(5432, 0).Truncate(-2).String()  // "5400"
New(-5432, 0).Truncate(-2).String() // "-5400"

func (*Decimal) UnmarshalBinary

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

UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.

Accepts the v1 format (header byte + optional uvarint mantissa) and the v2 extension formats for Decimal, Weight and Length (see BINARY_FORMAT.md). When fed a Weight or Length extension stream, the unit is read but discarded and only the scalar value (m × 10^exp) is returned.

func (*Decimal) UnmarshalJSON

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

UnmarshalJSON implements the json.Unmarshaler interface.

func (*Decimal) UnmarshalText

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

UnmarshalText implements the encoding.TextUnmarshaler interface for XML deserialization.

func (Decimal) Value

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

Value implements the driver.Valuer interface for database serialization.

type Length added in v0.9.0

type Length int64

Length represents a fixed-point decimal hold as a 64 bits integer including unit among 7 possible. integer value between -9007199254740991 and 9007199254740991 (or LengthMaxInt) can safely be used as Length using 'm' unit, example :

var a Length = 101 // a is a Length of value 101m

Note 0 is unitialized Length and its value for calculation is 0. Note you need to use Length method for calculation, you cannot use + - * / or any other operators unless Length is a real non-zero integer value with 'm' unit. Unitialized Length is useful when using JSON marshaling/unmarshaling.

Length has similar 64 bits representation like Decimal except 4 bits are used to encode length unit. Length mantissa has 53 bits instead of Decimal mantissa of 57 bits.

func NewLength added in v0.9.0

func NewLength(value int64, exp int32, unit string) (l Length, err error)

NewLength returns a new fixed-point decimal length, value * 10 ^ exp using unit.

func NewLengthFromBytes added in v0.9.0

func NewLengthFromBytes(value []byte) (Length, error)

NewLengthFromBytes returns a new Length from a slice of bytes representation.

If no length unit is given, 'm' is assumed.

func NewLengthFromDecimal added in v0.9.0

func NewLengthFromDecimal(value Decimal, unit string) (l Length, err error)

NewLengthFromDecimal converts a Decimal to Length using unit.

func NewLengthFromString added in v0.9.0

func NewLengthFromString(value string) (Length, error)

NewLengthFromString returns a new Length from a string representation.

If no length unit is given, 'm' is assumed.

Example:

l, err := NewLengthFromString("-123.45")
l2, err := NewLengthFromString(".0001m")
l3, err := NewLengthFromString("1.47000mm")
l4, err := NewLengthFromString("3.14e15 km")

func (Length) Abs added in v0.9.0

func (l Length) Abs() Length

Abs returns the absolute value of the length.

func (Length) Add added in v0.9.0

func (l1 Length) Add(l2 Length) Length

Add returns l1 + l2 using l1 unit.

Example:

l1, err := NewLengthFromString("123.45km")
l2, err := NewLengthFromString("550m")
l3 := l1.Add(l2)
println(l1.Add(l2))
println(l2.Add(l1))

Output:

124km
124000m

func (Length) BytesTo added in v0.9.0

func (l Length) BytesTo(b []byte) []byte

BytesTo appends the string representation of the decimal to a slice of byte, if the decimal is Null it appends 0.

func (Length) Compare added in v0.9.0

func (l1 Length) Compare(l2 Length) int

Compare compares the numbers represented by l1 and l2 without taking into account lost precision and returns:

-1 if l1 <  l2
 0 if l1 == l2
+1 if l1 >  l2

func (Length) Div added in v0.9.0

func (l Length) Div(d Decimal) Length

Div returns l / d using l unit. If it doesn't divide exactly, the result will have DivisionPrecision digits after the decimal point and loss bit will be set.

func (Length) GreaterThan added in v0.9.0

func (l1 Length) GreaterThan(l2 Length) bool

GreaterThan returns true when l1 is greater than l2 (l1 > l2).

func (Length) GreaterThanOrEqual added in v0.9.0

func (l1 Length) GreaterThanOrEqual(l2 Length) bool

GreaterThanOrEqual returns true when l1 is greater than or equal to l2 (l1 >= l2).

func (Length) IfNull added in v0.9.0

func (l Length) IfNull(defaultValue Length) Length

IfNull return

defaultValue if l == Null
l in any other cases

func (Length) IsExact added in v0.9.0

func (l Length) IsExact() bool

IsExact return true if a length has its loss bit not set, ie it has not lost its precision during computation or conversion.

func (Length) IsExactlyZero added in v0.9.0

func (l Length) IsExactlyZero() bool

IsExactlyZero return

true if l == Null or l == Zero
false if l == ~0 or l == -~0 or l == +~0
false if l < 0
false if l > 0

func (Length) IsInfinite added in v0.9.0

func (l Length) IsInfinite() bool

IsInfinite return

true if a l == +Inf or l == -Inf
false in any other case

func (Length) IsNaN added in v0.9.0

func (l Length) IsNaN() bool

IsNaN return

true if l is not a number (NaN)
false in any other case

func (Length) IsNegative added in v0.9.0

func (l Length) IsNegative() bool

IsNegative return

true if l < 0 or l == ~-0
false if l == Null or l == Zero or l == ~0
false if l > 0

func (Length) IsNull added in v0.9.0

func (l Length) IsNull() bool

IsNull return

true if l == Null
false if l == 0
false if l == ~0 or l == -~0 or l == +~0
false if l < 0
false if l > 0

func (Length) IsPositive added in v0.9.0

func (l Length) IsPositive() bool

IsPositive return

true if l > 0 or l == ~+0
false if l == Null or l == Zero or l == ~0
false if l < 0 or l == ~-0
false if l is NaN

func (Length) IsSet added in v0.9.0

func (l Length) IsSet() bool

IsSet return

false if l == Null
true if l == 0
true if l == ~0 or l == -~0 or l == +~0
true if l < 0
true if l > 0

func (Length) IsZero added in v0.9.0

func (l Length) IsZero() bool

IsZero return

true if l == Null or l == Zero
true if l == ~0 or l == -~0 or l == +~0
false if l < 0
false if l > 0

func (Length) LessThan added in v0.9.0

func (l1 Length) LessThan(l2 Length) bool

LessThan returns true when l1 is less than l2 (l1 < l2).

func (Length) LessThanOrEqual added in v0.9.0

func (l1 Length) LessThanOrEqual(l2 Length) bool

LessThanOrEqual returns true when l1 is less than or equal to l2 (l1 <= l2).

func (Length) MarshalBinary added in v1.0.1

func (l Length) MarshalBinary() (data []byte, err error)

MarshalBinary implements the encoding.BinaryMarshaler interface.

When the unit is m (the default unit code 0) the encoding is identical to a Decimal of the same scalar value (1-10 bytes). For any other unit the v2 Length extension format is used (see BINARY_FORMAT.md). Magic values (NaN, ±Inf, NearZero variants) always use the v1 magic byte and lose the unit info.

func (Length) MarshalJSON added in v0.9.0

func (l Length) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (Length) MarshalText added in v0.9.0

func (l Length) MarshalText() (text []byte, err error)

MarshalText implements the encoding.TextMarshaler interface for XML serialization.

func (Length) Mul added in v0.9.0

func (l Length) Mul(d Decimal) Length

Mul returns l * d using l unit.

func (Length) Sign added in v0.9.0

func (l Length) Sign() int

Sign return

0 if l == Null or l == Zero or l == ~0
1 if l > 0 or l == ~+0
-1 if l < 0 or l == ~-0
undefined (1 or -1) if l is NaN

func (Length) String added in v0.9.0

func (l Length) String() string

String returns the string representation of the length with the fixed point and unit.

Example:

l, err := NewLength(-12345, -3, "m")
println(l.String())

Output:

-12.345m

func (Length) Sub added in v0.9.0

func (l1 Length) Sub(l2 Length) Length

Sub returns l1 - l2 using l1 unit.

func (Length) Unit added in v0.9.0

func (l Length) Unit() string

Unit returns unit string of l.

Example:

l1, err := NewLengthFromString("100cm")
println(l1.Unit())

Output:

cm

func (*Length) UnmarshalBinary added in v1.0.1

func (l *Length) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.

Accepts the v1 format (assumed to be in m), the v2 Decimal extension (assumed to be in m), and the v2 Length extension (with explicit unit). A v2 Weight extension is rejected with ErrFormat.

func (*Length) UnmarshalJSON added in v0.9.0

func (l *Length) UnmarshalJSON(b []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

func (*Length) UnmarshalText added in v0.9.0

func (l *Length) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface for XML deserialization.

type Weight added in v0.2.0

type Weight int64

Weight represents a fixed-point decimal hold as a 64 bits integer including unit among 14 possible. integer value between -9007199254740991 and 9007199254740991 (or WeightMaxInt) can safely be used as Weight using 'kg' unit, example :

var a Weight = 101 // a is a Weight of value 101Kg

Note 0 is unitialized Weight and its value for calculation is 0. Note you need to use Weight method for calculation, you cannot use + - * / or any other operators unless Weight is a real non-zero integer value with 'kg' unit. Unitialized Weight is useful when using JSON marshaling/unmarshaling.

Weight has similar 64 bits representation like Decimal except 4 bits are used to encode weight unit. Weight mantissa has 53 bits instead of Decimal mantissa of 57 bits.

func NewWeight added in v0.3.0

func NewWeight(value int64, exp int32, unit string) (w Weight, err error)

NewWeight returns a new fixed-point decimal weight, value * 10 ^ exp using unit.

func NewWeightFromBytes added in v0.2.0

func NewWeightFromBytes(value []byte) (Weight, error)

NewWeightFromBytes returns a new Weight from a slice of bytes representation.

If no weight unit is given, 'kg' is assumed.

func NewWeightFromDecimal added in v0.3.0

func NewWeightFromDecimal(value Decimal, unit string) (w Weight, err error)

NewWeightFromDecimal converts a Decimal to Weight using unit.

func NewWeightFromString added in v0.2.0

func NewWeightFromString(value string) (Weight, error)

NewWeightFromString returns a new Weight from a string representation.

If no weight unit is given, 'kg' is assumed.

Example:

w, err := NewFromString("-123.45")
w2, err := NewFromString(".0001g")
w3, err := NewFromString("1.47000mg")
w4, err := NewFromString("3.14e15 t")

func (Weight) Abs added in v0.5.0

func (w Weight) Abs() Weight

Abs returns the absolute value of the weight.

func (Weight) Add added in v0.2.0

func (w1 Weight) Add(w2 Weight) Weight

Add returns w1 + w2 using w1 unit.

Example:

w1, err := NewWeightFromString("123.45kg")
w2, err := NewWeightFromString("550g")
w3 := w1.Add(w2)
println(w1.Add(w2))
println(w2.Add(w1))

Output:

124kg
124000g

func (Weight) BytesTo added in v0.5.0

func (w Weight) BytesTo(b []byte) []byte

BytesTo appends the string representation of the decimal to a slice of byte, if the decimal is Null it appends 0.

func (Weight) Compare added in v0.3.0

func (w1 Weight) Compare(w2 Weight) int

Compare compares the numbers represented by w1 and w2 without taking into account lost precision and returns:

-1 if w1 <  w2
 0 if w1 == w2
+1 if w1 >  w2

func (Weight) Div added in v0.5.0

func (w Weight) Div(d Decimal) Weight

Div returns w / d using w unit. If it doesn't divide exactly, the result will have DivisionPrecision digits after the decimal point and loss bit will be set.

func (Weight) GreaterThan added in v0.3.0

func (w1 Weight) GreaterThan(w2 Weight) bool

GreaterThan returns true when w1 is greater than w2 (w1 > w2).

func (Weight) GreaterThanOrEqual added in v0.3.0

func (w1 Weight) GreaterThanOrEqual(w2 Weight) bool

GreaterThanOrEqual returns true when w1 is greater than or equal to w2 (w1 >= w2).

func (Weight) IfNull added in v0.3.0

func (w Weight) IfNull(defaultValue Weight) Weight

IfNull return

defaultValue if w == Null
w in any other cases

func (Weight) IsExact added in v0.3.0

func (w Weight) IsExact() bool

IsExact return true if a weight has its loss bit not set, ie it has not lost its precision during computation or conversion.

func (Weight) IsExactlyZero added in v0.3.0

func (w Weight) IsExactlyZero() bool

IsExactlyZero return

true if w == Null or w == Zero
false if w == ~0 or w == -~0 or w == +~0
false if w < 0
false if w > 0

func (Weight) IsInfinite added in v0.3.0

func (w Weight) IsInfinite() bool

IsInfinite return

true if a w == +Inf or w == -Inf
false in any other case

func (Weight) IsNaN added in v0.3.0

func (w Weight) IsNaN() bool

IsNaN return

true if w is not a a number (NaN)
false in any other case

func (Weight) IsNegative added in v0.3.0

func (w Weight) IsNegative() bool

IsNegative return

true if w < 0 or w == ~-0
false if w == Null or w == Zero or w == ~0
false if w > 0

func (Weight) IsNull added in v0.3.0

func (w Weight) IsNull() bool

IsNull return

true if w == Null
false if w == 0
false if w == ~0 or w == -~0 or w == +~0
false if w < 0
false if w > 0

func (Weight) IsPositive added in v0.3.0

func (w Weight) IsPositive() bool

IsPositive return

true if w > 0 or w == ~+0
false if w == Null or w == Zero or w == ~0
false if w < 0 or w == ~-0
false if w is NaN

func (Weight) IsSet added in v0.3.0

func (w Weight) IsSet() bool

IsSet return

false if w == Null
true if w == 0
true if w == ~0 or w == -~0 or w == +~0
true if w < 0
true if w > 0

func (Weight) IsZero added in v0.3.0

func (w Weight) IsZero() bool

IsZero return

true if w == Null or w == Zero
true if w == ~0 or w == -~0 or w == +~0
false if w < 0
false if w > 0

func (Weight) LessThan added in v0.3.0

func (w1 Weight) LessThan(w2 Weight) bool

LessThan returns true when w1 is less than w2 (w1 < w2).

func (Weight) LessThanOrEqual added in v0.3.0

func (w1 Weight) LessThanOrEqual(w2 Weight) bool

LessThanOrEqual returns true when w1 is less than or equal to w2 (w1 <= w2).

func (Weight) MarshalBinary added in v1.0.1

func (w Weight) MarshalBinary() (data []byte, err error)

MarshalBinary implements the encoding.BinaryMarshaler interface.

When the unit is kg (the default unit code 0) the encoding is identical to a Decimal of the same scalar value (1-10 bytes), so a Weight in kg and a Decimal with the same value share the same byte sequence. For any other unit the v2 Weight extension format is used (see BINARY_FORMAT.md). Magic values (NaN, ±Inf, NearZero variants) always use the v1 magic byte and lose the unit info.

func (Weight) MarshalJSON added in v0.2.0

func (w Weight) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (Weight) MarshalText added in v0.2.1

func (w Weight) MarshalText() (text []byte, err error)

MarshalText implements the encoding.TextMarshaler interface for XML serialization.

func (Weight) Mul added in v0.2.0

func (w Weight) Mul(d Decimal) Weight

Mul returns w * d using w unit.

func (Weight) Sign added in v0.3.0

func (w Weight) Sign() int

Sign return

0 if w == Null or w == Zero or w == ~0
1 if w > 0 or w == ~+0
-1 if w < 0 or w == ~-0
undefined (1 or -1) if w is NaN

func (Weight) String added in v0.2.0

func (w Weight) String() string

String returns the string representation of the weight with the fixed point and unit.

Example:

d := NewWeight(-12345, -3, "kg")
println(d.String())

Output:

-12.345kg

func (Weight) Sub added in v0.2.0

func (w1 Weight) Sub(w2 Weight) Weight

Sub returns w1 - w2 using w1 unit.

func (Weight) Unit added in v0.2.0

func (w Weight) Unit() string

Unit returns unit string of w.

Example:

w1, err := NewWeightFromString("100g")
println(w1.Unit())

Output:

g

func (*Weight) UnmarshalBinary added in v1.0.1

func (w *Weight) UnmarshalBinary(data []byte) error

UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.

Accepts the v1 format (assumed to be in kg), the v2 Decimal extension (assumed to be in kg), and the v2 Weight extension (with explicit unit). A v2 Length extension is rejected with ErrFormat.

func (*Weight) UnmarshalJSON added in v0.2.0

func (w *Weight) UnmarshalJSON(b []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

func (*Weight) UnmarshalText added in v0.2.1

func (w *Weight) UnmarshalText(text []byte) error

UnmarshalText implements the encoding.TextUnmarshaler interface for XML deserialization.

Jump to

Keyboard shortcuts

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