github.com/cockroachdb/apd/v3@v3.2.0/decimal.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  // implied. See the License for the specific language governing
    13  // permissions and limitations under the License.
    14  
    15  package apd
    16  
    17  import (
    18  	"errors"
    19  	"fmt"
    20  	"strconv"
    21  	"strings"
    22  	"unsafe"
    23  
    24  	"database/sql/driver"
    25  )
    26  
    27  // Decimal is an arbitrary-precision decimal. Its value is:
    28  //
    29  //     Negative × Coeff × 10**Exponent
    30  //
    31  // Coeff must be positive. If it is negative results may be incorrect and
    32  // apd may panic.
    33  type Decimal struct {
    34  	Form     Form
    35  	Negative bool
    36  	Exponent int32
    37  	Coeff    BigInt
    38  }
    39  
    40  // Form specifies the form of a Decimal.
    41  type Form int8
    42  
    43  const (
    44  	// These constants must be in the following order. CmpTotal assumes that
    45  	// the order of these constants reflects the total order on decimals.
    46  
    47  	// Finite is the finite form.
    48  	Finite Form = iota
    49  	// Infinite is the infinite form.
    50  	Infinite
    51  	// NaNSignaling is the signaling NaN form. It will always raise the
    52  	// InvalidOperation condition during an operation.
    53  	NaNSignaling
    54  	// NaN is the NaN form.
    55  	NaN
    56  )
    57  
    58  var (
    59  	decimalNaN      = &Decimal{Form: NaN}
    60  	decimalInfinity = &Decimal{Form: Infinite}
    61  )
    62  
    63  //go:generate stringer -type=Form
    64  
    65  const (
    66  	// TODO(mjibson): MaxExponent is set because both upscale and Round
    67  	// perform a calculation of 10^x, where x is an exponent. This is done by
    68  	// big.Int.Exp. This restriction could be lifted if better algorithms were
    69  	// determined during upscale and Round that don't need to perform Exp.
    70  
    71  	// MaxExponent is the highest exponent supported. Exponents near this range will
    72  	// perform very slowly (many seconds per operation).
    73  	MaxExponent = 100000
    74  	// MinExponent is the lowest exponent supported with the same limitations as
    75  	// MaxExponent.
    76  	MinExponent = -MaxExponent
    77  )
    78  
    79  // New creates a new decimal with the given coefficient and exponent.
    80  func New(coeff int64, exponent int32) *Decimal {
    81  	d := new(Decimal)
    82  	d.SetFinite(coeff, exponent)
    83  	return d
    84  }
    85  
    86  // NewWithBigInt creates a new decimal with the given coefficient and exponent.
    87  func NewWithBigInt(coeff *BigInt, exponent int32) *Decimal {
    88  	d := new(Decimal)
    89  	d.Coeff.Set(coeff)
    90  	if d.Coeff.Sign() < 0 {
    91  		d.Negative = true
    92  		d.Coeff.Abs(&d.Coeff)
    93  	}
    94  	d.Exponent = exponent
    95  	return d
    96  }
    97  
    98  func consumePrefix(s, prefix string) (string, bool) {
    99  	if strings.HasPrefix(s, prefix) {
   100  		return s[len(prefix):], true
   101  	}
   102  	return s, false
   103  }
   104  
   105  func (d *Decimal) setString(c *Context, s string) (Condition, error) {
   106  	orig := s
   107  	s, d.Negative = consumePrefix(s, "-")
   108  	if !d.Negative {
   109  		s, _ = consumePrefix(s, "+")
   110  	}
   111  	s = strings.ToLower(s)
   112  	d.Exponent = 0
   113  	d.Coeff.SetInt64(0)
   114  	// Until there are no parse errors, leave as NaN.
   115  	d.Form = NaN
   116  	if strings.HasPrefix(s, "-") || strings.HasPrefix(s, "+") {
   117  		return 0, fmt.Errorf("could not parse: %s", orig)
   118  	}
   119  	switch s {
   120  	case "infinity", "inf":
   121  		d.Form = Infinite
   122  		return 0, nil
   123  	}
   124  	isNaN := false
   125  	s, consumed := consumePrefix(s, "nan")
   126  	if consumed {
   127  		isNaN = true
   128  	}
   129  	s, consumed = consumePrefix(s, "snan")
   130  	if consumed {
   131  		isNaN = true
   132  		d.Form = NaNSignaling
   133  	}
   134  	if isNaN {
   135  		if s != "" {
   136  			// We ignore these digits, but must verify them.
   137  			_, err := strconv.ParseUint(s, 10, 64)
   138  			if err != nil {
   139  				return 0, fmt.Errorf("parse payload: %s: %w", s, err)
   140  			}
   141  		}
   142  		return 0, nil
   143  	}
   144  
   145  	exps := make([]int64, 0, 2)
   146  	if i := strings.IndexByte(s, 'e'); i >= 0 {
   147  		exp, err := strconv.ParseInt(s[i+1:], 10, 32)
   148  		if err != nil {
   149  			return 0, fmt.Errorf("parse exponent: %s: %w", s[i+1:], err)
   150  		}
   151  		exps = append(exps, exp)
   152  		s = s[:i]
   153  	}
   154  	if i := strings.IndexByte(s, '.'); i >= 0 {
   155  		exp := int64(len(s) - i - 1)
   156  		exps = append(exps, -exp)
   157  		s = s[:i] + s[i+1:]
   158  	}
   159  	if _, ok := d.Coeff.SetString(s, 10); !ok {
   160  		return 0, fmt.Errorf("parse mantissa: %s", s)
   161  	}
   162  	// No parse errors, can now flag as finite.
   163  	d.Form = Finite
   164  	return c.goError(d.setExponent(c, unknownNumDigits, 0, exps...))
   165  }
   166  
   167  // NewFromString creates a new decimal from s. It has no restrictions on
   168  // exponents or precision.
   169  func NewFromString(s string) (*Decimal, Condition, error) {
   170  	return BaseContext.NewFromString(s)
   171  }
   172  
   173  // SetString sets d to s and returns d. It has no restrictions on exponents
   174  // or precision.
   175  func (d *Decimal) SetString(s string) (*Decimal, Condition, error) {
   176  	return BaseContext.SetString(d, s)
   177  }
   178  
   179  // NewFromString creates a new decimal from s. The returned Decimal has its
   180  // exponents restricted by the context and its value rounded if it contains more
   181  // digits than the context's precision.
   182  func (c *Context) NewFromString(s string) (*Decimal, Condition, error) {
   183  	d := new(Decimal)
   184  	return c.SetString(d, s)
   185  }
   186  
   187  // SetString sets d to s and returns d. The returned Decimal has its exponents
   188  // restricted by the context and its value rounded if it contains more digits
   189  // than the context's precision.
   190  func (c *Context) SetString(d *Decimal, s string) (*Decimal, Condition, error) {
   191  	res, err := d.setString(c, s)
   192  	if err != nil {
   193  		return nil, 0, err
   194  	}
   195  	res |= c.round(d, d)
   196  	_, err = c.goError(res)
   197  	return d, res, err
   198  }
   199  
   200  // Set sets d's fields to the values of x and returns d.
   201  //gcassert:inline
   202  func (d *Decimal) Set(x *Decimal) *Decimal {
   203  	if d == x {
   204  		return d
   205  	}
   206  	return d.setSlow(x)
   207  }
   208  
   209  // setSlow is split from Set to allow the aliasing fast-path to be
   210  // inlined in callers.
   211  func (d *Decimal) setSlow(x *Decimal) *Decimal {
   212  	d.Form = x.Form
   213  	d.Negative = x.Negative
   214  	d.Exponent = x.Exponent
   215  	d.Coeff.Set(&x.Coeff)
   216  	return d
   217  }
   218  
   219  // SetInt64 sets d to x and returns d.
   220  func (d *Decimal) SetInt64(x int64) *Decimal {
   221  	return d.SetFinite(x, 0)
   222  }
   223  
   224  // SetFinite sets d to x with exponent e and returns d.
   225  func (d *Decimal) SetFinite(x int64, e int32) *Decimal {
   226  	d.setCoefficient(x)
   227  	d.Exponent = e
   228  	return d
   229  }
   230  
   231  // setCoefficient sets d's coefficient and negative value to x and its Form
   232  // to Finite The exponent is not changed. Since the exponent is not changed
   233  // (and this is thus easy to misuse), this is unexported for internal use only.
   234  func (d *Decimal) setCoefficient(x int64) {
   235  	d.Negative = x < 0
   236  	d.Coeff.SetInt64(x)
   237  	d.Coeff.Abs(&d.Coeff)
   238  	d.Form = Finite
   239  }
   240  
   241  // SetFloat64 sets d's Coefficient and Exponent to x and returns d. d will
   242  // hold the exact value of f.
   243  func (d *Decimal) SetFloat64(f float64) (*Decimal, error) {
   244  	_, _, err := d.SetString(strconv.FormatFloat(f, 'E', -1, 64))
   245  	return d, err
   246  }
   247  
   248  // Int64 returns the int64 representation of x. If x cannot be represented in an
   249  // int64, an error is returned.
   250  func (d *Decimal) Int64() (int64, error) {
   251  	if d.Form != Finite {
   252  		return 0, fmt.Errorf("%s is not finite", d.String())
   253  	}
   254  	var integ, frac Decimal
   255  	d.Modf(&integ, &frac)
   256  	if !frac.IsZero() {
   257  		return 0, fmt.Errorf("%s: has fractional part", d.String())
   258  	}
   259  	var ed ErrDecimal
   260  	if integ.Cmp(decimalMaxInt64) > 0 {
   261  		return 0, fmt.Errorf("%s: greater than max int64", d.String())
   262  	}
   263  	if integ.Cmp(decimalMinInt64) < 0 {
   264  		return 0, fmt.Errorf("%s: less than min int64", d.String())
   265  	}
   266  	if err := ed.Err(); err != nil {
   267  		return 0, err
   268  	}
   269  	v := integ.Coeff.Int64()
   270  	for i := int32(0); i < integ.Exponent; i++ {
   271  		v *= 10
   272  	}
   273  	if d.Negative {
   274  		v = -v
   275  	}
   276  	return v, nil
   277  }
   278  
   279  // Float64 returns the float64 representation of x. This conversion may lose
   280  // data (see strconv.ParseFloat for caveats).
   281  func (d *Decimal) Float64() (float64, error) {
   282  	return strconv.ParseFloat(d.String(), 64)
   283  }
   284  
   285  const (
   286  	errExponentOutOfRangeStr = "exponent out of range"
   287  
   288  	unknownNumDigits = int64(-1)
   289  )
   290  
   291  // setExponent sets d's Exponent to the sum of xs. Each value and the sum
   292  // of xs must fit within an int32. An error occurs if the sum is outside of
   293  // the MaxExponent or MinExponent range. nd is the number of digits in d, as
   294  // computed by NumDigits. Callers can pass unknownNumDigits to indicate that
   295  // they have not yet computed this digit count, in which case setExponent will
   296  // do so. res is any Condition previously set for this operation, which can
   297  // cause Underflow to be set if, for example, Inexact is already set.
   298  func (d *Decimal) setExponent(c *Context, nd int64, res Condition, xs ...int64) Condition {
   299  	var sum int64
   300  	for _, x := range xs {
   301  		if x > MaxExponent {
   302  			return SystemOverflow | Overflow
   303  		}
   304  		if x < MinExponent {
   305  			return SystemUnderflow | Underflow
   306  		}
   307  		sum += x
   308  	}
   309  	r := int32(sum)
   310  
   311  	if nd == unknownNumDigits {
   312  		nd = d.NumDigits()
   313  	}
   314  	// adj is the adjusted exponent: exponent + clength - 1
   315  	adj := sum + nd - 1
   316  	// Make sure it is less than the system limits.
   317  	if adj > MaxExponent {
   318  		return SystemOverflow | Overflow
   319  	}
   320  	if adj < MinExponent {
   321  		return SystemUnderflow | Underflow
   322  	}
   323  	v := int32(adj)
   324  
   325  	// d is subnormal.
   326  	if v < c.MinExponent {
   327  		if !d.IsZero() {
   328  			res |= Subnormal
   329  		}
   330  		Etiny := c.MinExponent - (int32(c.Precision) - 1)
   331  		// Only need to round if exponent < Etiny.
   332  		if r < Etiny {
   333  			// We need to take off (r - Etiny) digits. Split up d.Coeff into integer and
   334  			// fractional parts and do operations similar Round. We avoid calling Round
   335  			// directly because it calls setExponent and modifies the result's exponent
   336  			// and coeff in ways that would be wrong here.
   337  			var tmp Decimal
   338  			tmp.Coeff.Set(&d.Coeff)
   339  			tmp.Exponent = r - Etiny
   340  			var integ, frac Decimal
   341  			tmp.Modf(&integ, &frac)
   342  			frac.Abs(&frac)
   343  			if !frac.IsZero() {
   344  				res |= Inexact
   345  				if c.Rounding.ShouldAddOne(&integ.Coeff, integ.Negative, frac.Cmp(decimalHalf)) {
   346  					integ.Coeff.Add(&integ.Coeff, bigOne)
   347  				}
   348  			}
   349  			if integ.IsZero() {
   350  				res |= Clamped
   351  			}
   352  			r = Etiny
   353  			d.Coeff.Set(&integ.Coeff)
   354  			res |= Rounded
   355  		}
   356  	} else if v > c.MaxExponent {
   357  		if d.IsZero() {
   358  			res |= Clamped
   359  			r = c.MaxExponent
   360  		} else {
   361  			res |= Overflow | Inexact
   362  			d.Form = Infinite
   363  		}
   364  	}
   365  
   366  	if res.Inexact() && res.Subnormal() {
   367  		res |= Underflow
   368  	}
   369  
   370  	d.Exponent = r
   371  	return res
   372  }
   373  
   374  // upscale converts a and b to BigInts with the same scaling. It returns
   375  // them with this scaling, along with the scaling. An error can be produced
   376  // if the resulting scale factor is out of range. The tmp argument must be
   377  // provided and can be (but won't always be) one of the return values.
   378  func upscale(a, b *Decimal, tmp *BigInt) (*BigInt, *BigInt, int32, error) {
   379  	if a.Exponent == b.Exponent {
   380  		return &a.Coeff, &b.Coeff, a.Exponent, nil
   381  	}
   382  	swapped := false
   383  	if a.Exponent < b.Exponent {
   384  		swapped = true
   385  		b, a = a, b
   386  	}
   387  	s := int64(a.Exponent) - int64(b.Exponent)
   388  	// TODO(mjibson): figure out a better way to upscale numbers with highly
   389  	// differing exponents.
   390  	if s > MaxExponent {
   391  		return nil, nil, 0, errors.New(errExponentOutOfRangeStr)
   392  	}
   393  	x := tmp
   394  	e := tableExp10(s, x)
   395  	x.Mul(&a.Coeff, e)
   396  	y := &b.Coeff
   397  	if swapped {
   398  		x, y = y, x
   399  	}
   400  	return x, y, b.Exponent, nil
   401  }
   402  
   403  // setBig sets b to d's coefficient with negative.
   404  func (d *Decimal) setBig(b *BigInt) *BigInt {
   405  	b.Set(&d.Coeff)
   406  	if d.Negative {
   407  		b.Neg(b)
   408  	}
   409  	return b
   410  }
   411  
   412  // CmpTotal compares d and x using their abstract representation rather
   413  // than their numerical value. A total ordering is defined for all possible
   414  // abstract representations, as described below. If the first operand is
   415  // lower in the total order than the second operand then the result is -1,
   416  // if the operands have the same abstract representation then the result is
   417  // 0, and if the first operand is higher in the total order than the second
   418  // operand then the result is 1.
   419  //
   420  // Numbers (representations which are not NaNs) are ordered such that a
   421  // larger numerical value is higher in the ordering. If two representations
   422  // have the same numerical value then the exponent is taken into account;
   423  // larger (more positive) exponents are higher in the ordering.
   424  //
   425  // For example, the following values are ordered from lowest to highest. Note
   426  // the difference in ordering between 1.2300 and 1.23.
   427  //
   428  //   -NaN
   429  //   -NaNSignaling
   430  //   -Infinity
   431  //   -127
   432  //   -1.00
   433  //   -1
   434  //   -0.000
   435  //   -0
   436  //   0
   437  //   1.2300
   438  //   1.23
   439  //   1E+9
   440  //   Infinity
   441  //   NaNSignaling
   442  //   NaN
   443  //
   444  func (d *Decimal) CmpTotal(x *Decimal) int {
   445  	do := d.cmpOrder()
   446  	xo := x.cmpOrder()
   447  
   448  	if do < xo {
   449  		return -1
   450  	}
   451  	if do > xo {
   452  		return 1
   453  	}
   454  
   455  	switch d.Form {
   456  	case Finite:
   457  		// d and x have the same sign and form, compare their value.
   458  		if c := d.Cmp(x); c != 0 {
   459  			return c
   460  		}
   461  
   462  		lt := -1
   463  		gt := 1
   464  		if d.Negative {
   465  			lt = 1
   466  			gt = -1
   467  		}
   468  
   469  		// Values are equal, compare exponents.
   470  		if d.Exponent < x.Exponent {
   471  			return lt
   472  		}
   473  		if d.Exponent > x.Exponent {
   474  			return gt
   475  		}
   476  		return 0
   477  
   478  	case Infinite:
   479  		return 0
   480  
   481  	default:
   482  		return d.Coeff.Cmp(&x.Coeff)
   483  	}
   484  }
   485  
   486  func (d *Decimal) cmpOrder() int {
   487  	v := int(d.Form) + 1
   488  	if d.Negative {
   489  		v = -v
   490  	}
   491  	return v
   492  }
   493  
   494  // Cmp compares x and y and sets d to:
   495  //
   496  //   -1 if x <  y
   497  //    0 if x == y
   498  //   +1 if x >  y
   499  //
   500  // This comparison respects the normal rules of special values (like NaN),
   501  // and does not compare them.
   502  func (c *Context) Cmp(d, x, y *Decimal) (Condition, error) {
   503  	if c.shouldSetAsNaN(x, y) {
   504  		return c.setAsNaN(d, x, y)
   505  	}
   506  	v := x.Cmp(y)
   507  	d.SetInt64(int64(v))
   508  	return 0, nil
   509  }
   510  
   511  // Cmp compares d and x and returns:
   512  //
   513  //   -1 if d <  x
   514  //    0 if d == x
   515  //   +1 if d >  x
   516  //   undefined if d or x are NaN
   517  //
   518  func (d *Decimal) Cmp(x *Decimal) int {
   519  	ds := d.Sign()
   520  	xs := x.Sign()
   521  
   522  	// First compare signs.
   523  	if ds < xs {
   524  		return -1
   525  	} else if ds > xs {
   526  		return 1
   527  	} else if ds == 0 && xs == 0 {
   528  		return 0
   529  	}
   530  
   531  	// Use gt and lt here with flipped signs if d is negative. gt and lt then
   532  	// allow for simpler comparisons since we can ignore the sign of the decimals
   533  	// and only worry about the form and value.
   534  	gt := 1
   535  	lt := -1
   536  	if ds == -1 {
   537  		gt = -1
   538  		lt = 1
   539  	}
   540  
   541  	if d.Form == Infinite {
   542  		if x.Form == Infinite {
   543  			return 0
   544  		}
   545  		return gt
   546  	} else if x.Form == Infinite {
   547  		return lt
   548  	}
   549  
   550  	if d.Exponent == x.Exponent {
   551  		cmp := d.Coeff.Cmp(&x.Coeff)
   552  		if ds < 0 {
   553  			cmp = -cmp
   554  		}
   555  		return cmp
   556  	}
   557  
   558  	// Next compare adjusted exponents.
   559  	dn := d.NumDigits() + int64(d.Exponent)
   560  	xn := x.NumDigits() + int64(x.Exponent)
   561  	if dn < xn {
   562  		return lt
   563  	} else if dn > xn {
   564  		return gt
   565  	}
   566  
   567  	// Now have to use aligned BigInts. This function previously used upscale to
   568  	// align in all cases, but that requires an error in the return value. upscale
   569  	// does that so that it can fail if it needs to take the Exp of too-large a
   570  	// number, which is very slow. The only way for that to happen here is for d
   571  	// and x's coefficients to be of hugely differing values. That is practically
   572  	// more difficult, so we are assuming the user is already comfortable with
   573  	// slowness in those operations.
   574  
   575  	var cmp int
   576  	if d.Exponent < x.Exponent {
   577  		var xScaled, tmpE BigInt
   578  		xScaled.Set(&x.Coeff)
   579  		xScaled.Mul(&xScaled, tableExp10(int64(x.Exponent)-int64(d.Exponent), &tmpE))
   580  		cmp = d.Coeff.Cmp(&xScaled)
   581  	} else {
   582  		var dScaled, tmpE BigInt
   583  		dScaled.Set(&d.Coeff)
   584  		dScaled.Mul(&dScaled, tableExp10(int64(d.Exponent)-int64(x.Exponent), &tmpE))
   585  		cmp = dScaled.Cmp(&x.Coeff)
   586  	}
   587  	if ds < 0 {
   588  		cmp = -cmp
   589  	}
   590  	return cmp
   591  }
   592  
   593  // Sign returns, if d is Finite:
   594  //
   595  //	-1 if d <  0
   596  //	 0 if d == 0 or -0
   597  //	+1 if d >  0
   598  //
   599  // Otherwise (if d is Infinite or NaN):
   600  //
   601  //	-1 if d.Negative == true
   602  //	+1 if d.Negative == false
   603  //
   604  func (d *Decimal) Sign() int {
   605  	if d.Form == Finite && d.Coeff.Sign() == 0 {
   606  		return 0
   607  	}
   608  	if d.Negative {
   609  		return -1
   610  	}
   611  	return 1
   612  }
   613  
   614  // IsZero returns true if d == 0 or -0.
   615  func (d *Decimal) IsZero() bool {
   616  	return d.Sign() == 0
   617  }
   618  
   619  // Modf sets integ to the integral part of d and frac to the fractional part
   620  // such that d = integ+frac. If d is negative, both integ or frac will be either
   621  // 0 or negative. integ.Exponent will be >= 0; frac.Exponent will be <= 0.
   622  // Either argument can be nil, preventing it from being set.
   623  func (d *Decimal) Modf(integ, frac *Decimal) {
   624  	if integ == nil && frac == nil {
   625  		return
   626  	}
   627  
   628  	neg := d.Negative
   629  
   630  	// No fractional part.
   631  	if d.Exponent > 0 {
   632  		if frac != nil {
   633  			frac.Negative = neg
   634  			frac.Exponent = 0
   635  			frac.Coeff.SetInt64(0)
   636  		}
   637  		if integ != nil {
   638  			integ.Set(d)
   639  		}
   640  		return
   641  	}
   642  	nd := d.NumDigits()
   643  	exp := -int64(d.Exponent)
   644  	// d < 0 because exponent is larger than number of digits.
   645  	if exp > nd {
   646  		if integ != nil {
   647  			integ.Negative = neg
   648  			integ.Exponent = 0
   649  			integ.Coeff.SetInt64(0)
   650  		}
   651  		if frac != nil {
   652  			frac.Set(d)
   653  		}
   654  		return
   655  	}
   656  
   657  	var tmpE BigInt
   658  	e := tableExp10(exp, &tmpE)
   659  
   660  	var icoeff *BigInt
   661  	if integ != nil {
   662  		icoeff = &integ.Coeff
   663  		integ.Exponent = 0
   664  		integ.Negative = neg
   665  	} else {
   666  		// This is the integ == nil branch, and we already checked if both integ and
   667  		// frac were nil above, so frac can never be nil in this branch.
   668  		icoeff = new(BigInt)
   669  	}
   670  
   671  	if frac != nil {
   672  		icoeff.QuoRem(&d.Coeff, e, &frac.Coeff)
   673  		frac.Exponent = d.Exponent
   674  		frac.Negative = neg
   675  	} else {
   676  		// This is the frac == nil, which means integ must not be nil since they both
   677  		// can't be due to the check above.
   678  		icoeff.Quo(&d.Coeff, e)
   679  	}
   680  }
   681  
   682  // Neg sets d to -x and returns d.
   683  func (d *Decimal) Neg(x *Decimal) *Decimal {
   684  	d.Set(x)
   685  	if d.IsZero() {
   686  		d.Negative = false
   687  	} else {
   688  		d.Negative = !d.Negative
   689  	}
   690  	return d
   691  }
   692  
   693  // Abs sets d to |x| and returns d.
   694  func (d *Decimal) Abs(x *Decimal) *Decimal {
   695  	d.Set(x)
   696  	d.Negative = false
   697  	return d
   698  }
   699  
   700  // Reduce sets d to x with all trailing zeros removed and returns d and the
   701  // number of zeros removed.
   702  func (d *Decimal) Reduce(x *Decimal) (*Decimal, int) {
   703  	if x.Form != Finite {
   704  		d.Set(x)
   705  		return d, 0
   706  	}
   707  	var nd int
   708  	neg := false
   709  	switch x.Sign() {
   710  	case 0:
   711  		nd = int(d.NumDigits())
   712  		d.SetInt64(0)
   713  		return d, nd - 1
   714  	case -1:
   715  		neg = true
   716  	}
   717  	d.Set(x)
   718  
   719  	// Use a uint64 for the division if possible.
   720  	if d.Coeff.IsUint64() {
   721  		i := d.Coeff.Uint64()
   722  		for i >= 10000 && i%10000 == 0 {
   723  			i /= 10000
   724  			nd += 4
   725  		}
   726  		for i%10 == 0 {
   727  			i /= 10
   728  			nd++
   729  		}
   730  		if nd != 0 {
   731  			d.Exponent += int32(nd)
   732  			d.Coeff.SetUint64(i)
   733  			d.Negative = neg
   734  		}
   735  		return d, nd
   736  	}
   737  
   738  	// Divide by 10 in a loop. In benchmarks of reduce0.decTest, this is 20%
   739  	// faster than converting to a string and trimming the 0s from the end.
   740  	var z, r BigInt
   741  	d.setBig(&z)
   742  	for {
   743  		z.QuoRem(&d.Coeff, bigTen, &r)
   744  		if r.Sign() == 0 {
   745  			d.Coeff.Set(&z)
   746  			nd++
   747  		} else {
   748  			break
   749  		}
   750  	}
   751  	d.Exponent += int32(nd)
   752  	return d, nd
   753  }
   754  
   755  const decimalSize = unsafe.Sizeof(Decimal{})
   756  
   757  // Size returns the total memory footprint of d in bytes.
   758  func (d *Decimal) Size() uintptr {
   759  	return decimalSize - bigIntSize + d.Coeff.Size()
   760  }
   761  
   762  // Value implements the database/sql/driver.Valuer interface. It converts d to a
   763  // string.
   764  func (d Decimal) Value() (driver.Value, error) {
   765  	return d.String(), nil
   766  }
   767  
   768  // Scan implements the database/sql.Scanner interface. It supports string,
   769  // []byte, int64, float64.
   770  func (d *Decimal) Scan(src interface{}) error {
   771  	switch src := src.(type) {
   772  	case []byte:
   773  		_, _, err := d.SetString(string(src))
   774  		return err
   775  	case string:
   776  		_, _, err := d.SetString(src)
   777  		return err
   778  	case int64:
   779  		d.SetInt64(src)
   780  		return nil
   781  	case float64:
   782  		_, err := d.SetFloat64(src)
   783  		return err
   784  	default:
   785  		return fmt.Errorf("could not convert %T to Decimal", src)
   786  	}
   787  }
   788  
   789  // UnmarshalText implements the encoding.TextUnmarshaler interface.
   790  func (d *Decimal) UnmarshalText(b []byte) error {
   791  	_, _, err := d.SetString(string(b))
   792  	return err
   793  }
   794  
   795  // MarshalText implements the encoding.TextMarshaler interface.
   796  func (d *Decimal) MarshalText() ([]byte, error) {
   797  	if d == nil {
   798  		return []byte("<nil>"), nil
   799  	}
   800  	return []byte(d.String()), nil
   801  }
   802  
   803  // NullDecimal represents a string that may be null. NullDecimal implements
   804  // the database/sql.Scanner interface so it can be used as a scan destination:
   805  //
   806  //  var d NullDecimal
   807  //  err := db.QueryRow("SELECT num FROM foo WHERE id=?", id).Scan(&d)
   808  //  ...
   809  //  if d.Valid {
   810  //     // use d.Decimal
   811  //  } else {
   812  //     // NULL value
   813  //  }
   814  //
   815  type NullDecimal struct {
   816  	Decimal Decimal
   817  	Valid   bool // Valid is true if Decimal is not NULL
   818  }
   819  
   820  // Scan implements the database/sql.Scanner interface.
   821  func (nd *NullDecimal) Scan(value interface{}) error {
   822  	if value == nil {
   823  		nd.Valid = false
   824  		return nil
   825  	}
   826  	nd.Valid = true
   827  	return nd.Decimal.Scan(value)
   828  }
   829  
   830  // Value implements the database/sql/driver.Valuer interface.
   831  func (nd NullDecimal) Value() (driver.Value, error) {
   832  	if !nd.Valid {
   833  		return nil, nil
   834  	}
   835  	return nd.Decimal.Value()
   836  }