decimal.go raw

   1  // Package decimal implements an arbitrary precision fixed-point decimal.
   2  //
   3  // The zero-value of a Decimal is 0, as you would expect.
   4  //
   5  // The best way to create a new Decimal is to use decimal.NewFromString, ex:
   6  //
   7  //	n, err := decimal.NewFromString("-123.4567")
   8  //	n.String() // output: "-123.4567"
   9  //
  10  // To use Decimal as part of a struct:
  11  //
  12  //	type StructName struct {
  13  //	    Number Decimal
  14  //	}
  15  //
  16  // Note: This can "only" represent numbers with a maximum of 2^31 digits after the decimal point.
  17  package decimal
  18  
  19  import (
  20  	"database/sql/driver"
  21  	"encoding/binary"
  22  	"fmt"
  23  	"math"
  24  	"math/big"
  25  	"regexp"
  26  	"strconv"
  27  	"strings"
  28  )
  29  
  30  // DivisionPrecision is the number of decimal places in the result when it
  31  // doesn't divide exactly.
  32  //
  33  // Example:
  34  //
  35  //	d1 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(3))
  36  //	d1.String() // output: "0.6666666666666667"
  37  //	d2 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(30000))
  38  //	d2.String() // output: "0.0000666666666667"
  39  //	d3 := decimal.NewFromFloat(20000).Div(decimal.NewFromFloat(3))
  40  //	d3.String() // output: "6666.6666666666666667"
  41  //	decimal.DivisionPrecision = 3
  42  //	d4 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(3))
  43  //	d4.String() // output: "0.667"
  44  var DivisionPrecision = 16
  45  
  46  // PowPrecisionNegativeExponent specifies the maximum precision of the result (digits after decimal point)
  47  // when calculating decimal power. Only used for cases where the exponent is a negative number.
  48  // This constant applies to Pow, PowInt32 and PowBigInt methods, PowWithPrecision method is not constrained by it.
  49  //
  50  // Example:
  51  //
  52  //	d1, err := decimal.NewFromFloat(15.2).PowInt32(-2)
  53  //	d1.String() // output: "0.0043282548476454"
  54  //
  55  //	decimal.PowPrecisionNegativeExponent = 24
  56  //	d2, err := decimal.NewFromFloat(15.2).PowInt32(-2)
  57  //	d2.String() // output: "0.004328254847645429362881"
  58  var PowPrecisionNegativeExponent = 16
  59  
  60  // MarshalJSONWithoutQuotes should be set to true if you want the decimal to
  61  // be JSON marshaled as a number, instead of as a string.
  62  // WARNING: this is dangerous for decimals with many digits, since many JSON
  63  // unmarshallers (ex: Javascript's) will unmarshal JSON numbers to IEEE 754
  64  // double-precision floating point numbers, which means you can potentially
  65  // silently lose precision.
  66  var MarshalJSONWithoutQuotes = false
  67  
  68  // ExpMaxIterations specifies the maximum number of iterations needed to calculate
  69  // precise natural exponent value using ExpHullAbrham method.
  70  var ExpMaxIterations = 1000
  71  
  72  // Zero constant, to make computations faster.
  73  // Zero should never be compared with == or != directly, please use decimal.Equal or decimal.Cmp instead.
  74  var Zero = New(0, 1)
  75  
  76  var zeroInt = big.NewInt(0)
  77  var oneInt = big.NewInt(1)
  78  var twoInt = big.NewInt(2)
  79  var fourInt = big.NewInt(4)
  80  var fiveInt = big.NewInt(5)
  81  var tenInt = big.NewInt(10)
  82  var twentyInt = big.NewInt(20)
  83  
  84  var factorials = []Decimal{New(1, 0)}
  85  
  86  // Decimal represents a fixed-point decimal. It is immutable.
  87  // number = value * 10 ^ exp
  88  type Decimal struct {
  89  	value *big.Int
  90  
  91  	// NOTE(vadim): this must be an int32, because we cast it to float64 during
  92  	// calculations. If exp is 64 bit, we might lose precision.
  93  	// If we cared about being able to represent every possible decimal, we
  94  	// could make exp a *big.Int but it would hurt performance and numbers
  95  	// like that are unrealistic.
  96  	exp int32
  97  }
  98  
  99  // New returns a new fixed-point decimal, value * 10 ^ exp.
 100  func New(value int64, exp int32) Decimal {
 101  	return Decimal{
 102  		value: big.NewInt(value),
 103  		exp:   exp,
 104  	}
 105  }
 106  
 107  // NewFromInt converts an int64 to Decimal.
 108  //
 109  // Example:
 110  //
 111  //	NewFromInt(123).String() // output: "123"
 112  //	NewFromInt(-10).String() // output: "-10"
 113  func NewFromInt(value int64) Decimal {
 114  	return Decimal{
 115  		value: big.NewInt(value),
 116  		exp:   0,
 117  	}
 118  }
 119  
 120  // NewFromInt32 converts an int32 to Decimal.
 121  //
 122  // Example:
 123  //
 124  //	NewFromInt(123).String() // output: "123"
 125  //	NewFromInt(-10).String() // output: "-10"
 126  func NewFromInt32(value int32) Decimal {
 127  	return Decimal{
 128  		value: big.NewInt(int64(value)),
 129  		exp:   0,
 130  	}
 131  }
 132  
 133  // NewFromUint64 converts an uint64 to Decimal.
 134  //
 135  // Example:
 136  //
 137  //	NewFromUint64(123).String() // output: "123"
 138  func NewFromUint64(value uint64) Decimal {
 139  	return Decimal{
 140  		value: new(big.Int).SetUint64(value),
 141  		exp:   0,
 142  	}
 143  }
 144  
 145  // NewFromBigInt returns a new Decimal from a big.Int, value * 10 ^ exp
 146  func NewFromBigInt(value *big.Int, exp int32) Decimal {
 147  	return Decimal{
 148  		value: new(big.Int).Set(value),
 149  		exp:   exp,
 150  	}
 151  }
 152  
 153  // NewFromBigRat returns a new Decimal from a big.Rat. The numerator and
 154  // denominator are divided and rounded to the given precision.
 155  //
 156  // Example:
 157  //
 158  //	d1 := NewFromBigRat(big.NewRat(0, 1), 0)    // output: "0"
 159  //	d2 := NewFromBigRat(big.NewRat(4, 5), 1)    // output: "0.8"
 160  //	d3 := NewFromBigRat(big.NewRat(1000, 3), 3) // output: "333.333"
 161  //	d4 := NewFromBigRat(big.NewRat(2, 7), 4)    // output: "0.2857"
 162  func NewFromBigRat(value *big.Rat, precision int32) Decimal {
 163  	return Decimal{
 164  		value: new(big.Int).Set(value.Num()),
 165  		exp:   0,
 166  	}.DivRound(Decimal{
 167  		value: new(big.Int).Set(value.Denom()),
 168  		exp:   0,
 169  	}, precision)
 170  }
 171  
 172  // NewFromString returns a new Decimal from a string representation.
 173  // Trailing zeroes are not trimmed.
 174  //
 175  // Example:
 176  //
 177  //	d, err := NewFromString("-123.45")
 178  //	d2, err := NewFromString(".0001")
 179  //	d3, err := NewFromString("1.47000")
 180  func NewFromString(value string) (Decimal, error) {
 181  	originalInput := value
 182  	var intString string
 183  	var exp int64
 184  
 185  	// Check if number is using scientific notation
 186  	eIndex := strings.IndexAny(value, "Ee")
 187  	if eIndex != -1 {
 188  		expInt, err := strconv.ParseInt(value[eIndex+1:], 10, 32)
 189  		if err != nil {
 190  			if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
 191  				return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", value)
 192  			}
 193  			return Decimal{}, fmt.Errorf("can't convert %s to decimal: exponent is not numeric", value)
 194  		}
 195  		value = value[:eIndex]
 196  		exp = expInt
 197  	}
 198  
 199  	pIndex := -1
 200  	vLen := len(value)
 201  	for i := 0; i < vLen; i++ {
 202  		if value[i] == '.' {
 203  			if pIndex > -1 {
 204  				return Decimal{}, fmt.Errorf("can't convert %s to decimal: too many .s", value)
 205  			}
 206  			pIndex = i
 207  		}
 208  	}
 209  
 210  	if pIndex == -1 {
 211  		// There is no decimal point, we can just parse the original string as
 212  		// an int
 213  		intString = value
 214  	} else {
 215  		if pIndex+1 < vLen {
 216  			intString = value[:pIndex] + value[pIndex+1:]
 217  		} else {
 218  			intString = value[:pIndex]
 219  		}
 220  		expInt := -len(value[pIndex+1:])
 221  		exp += int64(expInt)
 222  	}
 223  
 224  	var dValue *big.Int
 225  	// strconv.ParseInt is faster than new(big.Int).SetString so this is just a shortcut for strings we know won't overflow
 226  	if len(intString) <= 18 {
 227  		parsed64, err := strconv.ParseInt(intString, 10, 64)
 228  		if err != nil {
 229  			return Decimal{}, fmt.Errorf("can't convert %s to decimal", value)
 230  		}
 231  		dValue = big.NewInt(parsed64)
 232  	} else {
 233  		dValue = new(big.Int)
 234  		_, ok := dValue.SetString(intString, 10)
 235  		if !ok {
 236  			return Decimal{}, fmt.Errorf("can't convert %s to decimal", value)
 237  		}
 238  	}
 239  
 240  	if exp < math.MinInt32 || exp > math.MaxInt32 {
 241  		// NOTE(vadim): I doubt a string could realistically be this long
 242  		return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", originalInput)
 243  	}
 244  
 245  	return Decimal{
 246  		value: dValue,
 247  		exp:   int32(exp),
 248  	}, nil
 249  }
 250  
 251  // NewFromFormattedString returns a new Decimal from a formatted string representation.
 252  // The second argument - replRegexp, is a regular expression that is used to find characters that should be
 253  // removed from given decimal string representation. All matched characters will be replaced with an empty string.
 254  //
 255  // Example:
 256  //
 257  //	r := regexp.MustCompile("[$,]")
 258  //	d1, err := NewFromFormattedString("$5,125.99", r)
 259  //
 260  //	r2 := regexp.MustCompile("[_]")
 261  //	d2, err := NewFromFormattedString("1_000_000", r2)
 262  //
 263  //	r3 := regexp.MustCompile("[USD\\s]")
 264  //	d3, err := NewFromFormattedString("5000 USD", r3)
 265  func NewFromFormattedString(value string, replRegexp *regexp.Regexp) (Decimal, error) {
 266  	parsedValue := replRegexp.ReplaceAllString(value, "")
 267  	d, err := NewFromString(parsedValue)
 268  	if err != nil {
 269  		return Decimal{}, err
 270  	}
 271  	return d, nil
 272  }
 273  
 274  // RequireFromString returns a new Decimal from a string representation
 275  // or panics if NewFromString had returned an error.
 276  //
 277  // Example:
 278  //
 279  //	d := RequireFromString("-123.45")
 280  //	d2 := RequireFromString(".0001")
 281  func RequireFromString(value string) Decimal {
 282  	dec, err := NewFromString(value)
 283  	if err != nil {
 284  		panic(err)
 285  	}
 286  	return dec
 287  }
 288  
 289  // NewFromFloat converts a float64 to Decimal.
 290  //
 291  // The converted number will contain the number of significant digits that can be
 292  // represented in a float with reliable roundtrip.
 293  // This is typically 15 digits, but may be more in some cases.
 294  // See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.
 295  //
 296  // For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.
 297  //
 298  // NOTE: this will panic on NaN, +/-inf
 299  func NewFromFloat(value float64) Decimal {
 300  	if value == 0 {
 301  		return New(0, 0)
 302  	}
 303  	return newFromFloat(value, math.Float64bits(value), &float64info)
 304  }
 305  
 306  // NewFromFloat32 converts a float32 to Decimal.
 307  //
 308  // The converted number will contain the number of significant digits that can be
 309  // represented in a float with reliable roundtrip.
 310  // This is typically 6-8 digits depending on the input.
 311  // See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.
 312  //
 313  // For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.
 314  //
 315  // NOTE: this will panic on NaN, +/-inf
 316  func NewFromFloat32(value float32) Decimal {
 317  	if value == 0 {
 318  		return New(0, 0)
 319  	}
 320  	// XOR is workaround for https://github.com/golang/go/issues/26285
 321  	a := math.Float32bits(value) ^ 0x80808080
 322  	return newFromFloat(float64(value), uint64(a)^0x80808080, &float32info)
 323  }
 324  
 325  func newFromFloat(val float64, bits uint64, flt *floatInfo) Decimal {
 326  	if math.IsNaN(val) || math.IsInf(val, 0) {
 327  		panic(fmt.Sprintf("Cannot create a Decimal from %v", val))
 328  	}
 329  	exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
 330  	mant := bits & (uint64(1)<<flt.mantbits - 1)
 331  
 332  	switch exp {
 333  	case 0:
 334  		// denormalized
 335  		exp++
 336  
 337  	default:
 338  		// add implicit top bit
 339  		mant |= uint64(1) << flt.mantbits
 340  	}
 341  	exp += flt.bias
 342  
 343  	var d decimal
 344  	d.Assign(mant)
 345  	d.Shift(exp - int(flt.mantbits))
 346  	d.neg = bits>>(flt.expbits+flt.mantbits) != 0
 347  
 348  	roundShortest(&d, mant, exp, flt)
 349  	// If less than 19 digits, we can do calculation in an int64.
 350  	if d.nd < 19 {
 351  		tmp := int64(0)
 352  		m := int64(1)
 353  		for i := d.nd - 1; i >= 0; i-- {
 354  			tmp += m * int64(d.d[i]-'0')
 355  			m *= 10
 356  		}
 357  		if d.neg {
 358  			tmp *= -1
 359  		}
 360  		return Decimal{value: big.NewInt(tmp), exp: int32(d.dp) - int32(d.nd)}
 361  	}
 362  	dValue := new(big.Int)
 363  	dValue, ok := dValue.SetString(string(d.d[:d.nd]), 10)
 364  	if ok {
 365  		return Decimal{value: dValue, exp: int32(d.dp) - int32(d.nd)}
 366  	}
 367  
 368  	return NewFromFloatWithExponent(val, int32(d.dp)-int32(d.nd))
 369  }
 370  
 371  // NewFromFloatWithExponent converts a float64 to Decimal, with an arbitrary
 372  // number of fractional digits.
 373  //
 374  // Example:
 375  //
 376  //	NewFromFloatWithExponent(123.456, -2).String() // output: "123.46"
 377  func NewFromFloatWithExponent(value float64, exp int32) Decimal {
 378  	if math.IsNaN(value) || math.IsInf(value, 0) {
 379  		panic(fmt.Sprintf("Cannot create a Decimal from %v", value))
 380  	}
 381  
 382  	bits := math.Float64bits(value)
 383  	mant := bits & (1<<52 - 1)
 384  	exp2 := int32((bits >> 52) & (1<<11 - 1))
 385  	sign := bits >> 63
 386  
 387  	if exp2 == 0 {
 388  		// specials
 389  		if mant == 0 {
 390  			return Decimal{}
 391  		}
 392  		// subnormal
 393  		exp2++
 394  	} else {
 395  		// normal
 396  		mant |= 1 << 52
 397  	}
 398  
 399  	exp2 -= 1023 + 52
 400  
 401  	// normalizing base-2 values
 402  	for mant&1 == 0 {
 403  		mant = mant >> 1
 404  		exp2++
 405  	}
 406  
 407  	// maximum number of fractional base-10 digits to represent 2^N exactly cannot be more than -N if N<0
 408  	if exp < 0 && exp < exp2 {
 409  		if exp2 < 0 {
 410  			exp = exp2
 411  		} else {
 412  			exp = 0
 413  		}
 414  	}
 415  
 416  	// representing 10^M * 2^N as 5^M * 2^(M+N)
 417  	exp2 -= exp
 418  
 419  	temp := big.NewInt(1)
 420  	dMant := big.NewInt(int64(mant))
 421  
 422  	// applying 5^M
 423  	if exp > 0 {
 424  		temp = temp.SetInt64(int64(exp))
 425  		temp = temp.Exp(fiveInt, temp, nil)
 426  	} else if exp < 0 {
 427  		temp = temp.SetInt64(-int64(exp))
 428  		temp = temp.Exp(fiveInt, temp, nil)
 429  		dMant = dMant.Mul(dMant, temp)
 430  		temp = temp.SetUint64(1)
 431  	}
 432  
 433  	// applying 2^(M+N)
 434  	if exp2 > 0 {
 435  		dMant = dMant.Lsh(dMant, uint(exp2))
 436  	} else if exp2 < 0 {
 437  		temp = temp.Lsh(temp, uint(-exp2))
 438  	}
 439  
 440  	// rounding and downscaling
 441  	if exp > 0 || exp2 < 0 {
 442  		halfDown := new(big.Int).Rsh(temp, 1)
 443  		dMant = dMant.Add(dMant, halfDown)
 444  		dMant = dMant.Quo(dMant, temp)
 445  	}
 446  
 447  	if sign == 1 {
 448  		dMant = dMant.Neg(dMant)
 449  	}
 450  
 451  	return Decimal{
 452  		value: dMant,
 453  		exp:   exp,
 454  	}
 455  }
 456  
 457  // Copy returns a copy of decimal with the same value and exponent, but a different pointer to value.
 458  func (d Decimal) Copy() Decimal {
 459  	d.ensureInitialized()
 460  	return Decimal{
 461  		value: new(big.Int).Set(d.value),
 462  		exp:   d.exp,
 463  	}
 464  }
 465  
 466  // rescale returns a rescaled version of the decimal. Returned
 467  // decimal may be less precise if the given exponent is bigger
 468  // than the initial exponent of the Decimal.
 469  // NOTE: this will truncate, NOT round
 470  //
 471  // Example:
 472  //
 473  //	d := New(12345, -4)
 474  //	d2 := d.rescale(-1)
 475  //	d3 := d2.rescale(-4)
 476  //	println(d1)
 477  //	println(d2)
 478  //	println(d3)
 479  //
 480  // Output:
 481  //
 482  //	1.2345
 483  //	1.2
 484  //	1.2000
 485  func (d Decimal) rescale(exp int32) Decimal {
 486  	d.ensureInitialized()
 487  
 488  	if d.exp == exp {
 489  		return Decimal{
 490  			new(big.Int).Set(d.value),
 491  			d.exp,
 492  		}
 493  	}
 494  
 495  	// NOTE(vadim): must convert exps to float64 before - to prevent overflow
 496  	diff := math.Abs(float64(exp) - float64(d.exp))
 497  	value := new(big.Int).Set(d.value)
 498  
 499  	expScale := new(big.Int).Exp(tenInt, big.NewInt(int64(diff)), nil)
 500  	if exp > d.exp {
 501  		value = value.Quo(value, expScale)
 502  	} else if exp < d.exp {
 503  		value = value.Mul(value, expScale)
 504  	}
 505  
 506  	return Decimal{
 507  		value: value,
 508  		exp:   exp,
 509  	}
 510  }
 511  
 512  // Abs returns the absolute value of the decimal.
 513  func (d Decimal) Abs() Decimal {
 514  	if !d.IsNegative() {
 515  		return d
 516  	}
 517  	d.ensureInitialized()
 518  	d2Value := new(big.Int).Abs(d.value)
 519  	return Decimal{
 520  		value: d2Value,
 521  		exp:   d.exp,
 522  	}
 523  }
 524  
 525  // Add returns d + d2.
 526  func (d Decimal) Add(d2 Decimal) Decimal {
 527  	rd, rd2 := RescalePair(d, d2)
 528  
 529  	d3Value := new(big.Int).Add(rd.value, rd2.value)
 530  	return Decimal{
 531  		value: d3Value,
 532  		exp:   rd.exp,
 533  	}
 534  }
 535  
 536  // Sub returns d - d2.
 537  func (d Decimal) Sub(d2 Decimal) Decimal {
 538  	rd, rd2 := RescalePair(d, d2)
 539  
 540  	d3Value := new(big.Int).Sub(rd.value, rd2.value)
 541  	return Decimal{
 542  		value: d3Value,
 543  		exp:   rd.exp,
 544  	}
 545  }
 546  
 547  // Neg returns -d.
 548  func (d Decimal) Neg() Decimal {
 549  	d.ensureInitialized()
 550  	val := new(big.Int).Neg(d.value)
 551  	return Decimal{
 552  		value: val,
 553  		exp:   d.exp,
 554  	}
 555  }
 556  
 557  // Mul returns d * d2.
 558  func (d Decimal) Mul(d2 Decimal) Decimal {
 559  	d.ensureInitialized()
 560  	d2.ensureInitialized()
 561  
 562  	expInt64 := int64(d.exp) + int64(d2.exp)
 563  	if expInt64 > math.MaxInt32 || expInt64 < math.MinInt32 {
 564  		// NOTE(vadim): better to panic than give incorrect results, as
 565  		// Decimals are usually used for money
 566  		panic(fmt.Sprintf("exponent %v overflows an int32!", expInt64))
 567  	}
 568  
 569  	d3Value := new(big.Int).Mul(d.value, d2.value)
 570  	return Decimal{
 571  		value: d3Value,
 572  		exp:   int32(expInt64),
 573  	}
 574  }
 575  
 576  // Shift shifts the decimal in base 10.
 577  // It shifts left when shift is positive and right if shift is negative.
 578  // In simpler terms, the given value for shift is added to the exponent
 579  // of the decimal.
 580  func (d Decimal) Shift(shift int32) Decimal {
 581  	d.ensureInitialized()
 582  	return Decimal{
 583  		value: new(big.Int).Set(d.value),
 584  		exp:   d.exp + shift,
 585  	}
 586  }
 587  
 588  // Div returns d / d2. If it doesn't divide exactly, the result will have
 589  // DivisionPrecision digits after the decimal point.
 590  func (d Decimal) Div(d2 Decimal) Decimal {
 591  	return d.DivRound(d2, int32(DivisionPrecision))
 592  }
 593  
 594  // QuoRem does division with remainder
 595  // d.QuoRem(d2,precision) returns quotient q and remainder r such that
 596  //
 597  //	d = d2 * q + r, q an integer multiple of 10^(-precision)
 598  //	0 <= r < abs(d2) * 10 ^(-precision) if d>=0
 599  //	0 >= r > -abs(d2) * 10 ^(-precision) if d<0
 600  //
 601  // Note that precision<0 is allowed as input.
 602  func (d Decimal) QuoRem(d2 Decimal, precision int32) (Decimal, Decimal) {
 603  	d.ensureInitialized()
 604  	d2.ensureInitialized()
 605  	if d2.value.Sign() == 0 {
 606  		panic("decimal division by 0")
 607  	}
 608  	scale := -precision
 609  	e := int64(d.exp) - int64(d2.exp) - int64(scale)
 610  	if e > math.MaxInt32 || e < math.MinInt32 {
 611  		panic("overflow in decimal QuoRem")
 612  	}
 613  	var aa, bb, expo big.Int
 614  	var scalerest int32
 615  	// d = a 10^ea
 616  	// d2 = b 10^eb
 617  	if e < 0 {
 618  		aa = *d.value
 619  		expo.SetInt64(-e)
 620  		bb.Exp(tenInt, &expo, nil)
 621  		bb.Mul(d2.value, &bb)
 622  		scalerest = d.exp
 623  		// now aa = a
 624  		//     bb = b 10^(scale + eb - ea)
 625  	} else {
 626  		expo.SetInt64(e)
 627  		aa.Exp(tenInt, &expo, nil)
 628  		aa.Mul(d.value, &aa)
 629  		bb = *d2.value
 630  		scalerest = scale + d2.exp
 631  		// now aa = a ^ (ea - eb - scale)
 632  		//     bb = b
 633  	}
 634  	var q, r big.Int
 635  	q.QuoRem(&aa, &bb, &r)
 636  	dq := Decimal{value: &q, exp: scale}
 637  	dr := Decimal{value: &r, exp: scalerest}
 638  	return dq, dr
 639  }
 640  
 641  // DivRound divides and rounds to a given precision
 642  // i.e. to an integer multiple of 10^(-precision)
 643  //
 644  //	for a positive quotient digit 5 is rounded up, away from 0
 645  //	if the quotient is negative then digit 5 is rounded down, away from 0
 646  //
 647  // Note that precision<0 is allowed as input.
 648  func (d Decimal) DivRound(d2 Decimal, precision int32) Decimal {
 649  	// QuoRem already checks initialization
 650  	q, r := d.QuoRem(d2, precision)
 651  	// the actual rounding decision is based on comparing r*10^precision and d2/2
 652  	// instead compare 2 r 10 ^precision and d2
 653  	var rv2 big.Int
 654  	rv2.Abs(r.value)
 655  	rv2.Lsh(&rv2, 1)
 656  	// now rv2 = abs(r.value) * 2
 657  	r2 := Decimal{value: &rv2, exp: r.exp + precision}
 658  	// r2 is now 2 * r * 10 ^ precision
 659  	var c = r2.Cmp(d2.Abs())
 660  
 661  	if c < 0 {
 662  		return q
 663  	}
 664  
 665  	if d.value.Sign()*d2.value.Sign() < 0 {
 666  		return q.Sub(New(1, -precision))
 667  	}
 668  
 669  	return q.Add(New(1, -precision))
 670  }
 671  
 672  // Mod returns d % d2.
 673  func (d Decimal) Mod(d2 Decimal) Decimal {
 674  	_, r := d.QuoRem(d2, 0)
 675  	return r
 676  }
 677  
 678  // Pow returns d to the power of d2.
 679  // When exponent is negative the returned decimal will have maximum precision of PowPrecisionNegativeExponent places after decimal point.
 680  //
 681  // Pow returns 0 (zero-value of Decimal) instead of error for power operation edge cases, to handle those edge cases use PowWithPrecision
 682  // Edge cases not handled by Pow:
 683  //   - 0 ** 0 => undefined value
 684  //   - 0 ** y, where y < 0 => infinity
 685  //   - x ** y, where x < 0 and y is non-integer decimal => imaginary value
 686  //
 687  // Example:
 688  //
 689  //	d1 := decimal.NewFromFloat(4.0)
 690  //	d2 := decimal.NewFromFloat(4.0)
 691  //	res1 := d1.Pow(d2)
 692  //	res1.String() // output: "256"
 693  //
 694  //	d3 := decimal.NewFromFloat(5.0)
 695  //	d4 := decimal.NewFromFloat(5.73)
 696  //	res2 := d3.Pow(d4)
 697  //	res2.String() // output: "10118.08037125"
 698  func (d Decimal) Pow(d2 Decimal) Decimal {
 699  	baseSign := d.Sign()
 700  	expSign := d2.Sign()
 701  
 702  	if baseSign == 0 {
 703  		if expSign == 0 {
 704  			return Decimal{}
 705  		}
 706  		if expSign == 1 {
 707  			return Decimal{zeroInt, 0}
 708  		}
 709  		if expSign == -1 {
 710  			return Decimal{}
 711  		}
 712  	}
 713  
 714  	if expSign == 0 {
 715  		return Decimal{oneInt, 0}
 716  	}
 717  
 718  	// TODO: optimize extraction of fractional part
 719  	one := Decimal{oneInt, 0}
 720  	expIntPart, expFracPart := d2.QuoRem(one, 0)
 721  
 722  	if baseSign == -1 && !expFracPart.IsZero() {
 723  		return Decimal{}
 724  	}
 725  
 726  	intPartPow, _ := d.PowBigInt(expIntPart.value)
 727  
 728  	// if exponent is an integer we don't need to calculate d1**frac(d2)
 729  	if expFracPart.value.Sign() == 0 {
 730  		return intPartPow
 731  	}
 732  
 733  	// TODO: optimize NumDigits for more performant precision adjustment
 734  	digitsBase := d.NumDigits()
 735  	digitsExponent := d2.NumDigits()
 736  
 737  	precision := digitsBase
 738  
 739  	if digitsExponent > precision {
 740  		precision += digitsExponent
 741  	}
 742  
 743  	precision += 6
 744  
 745  	// Calculate x ** frac(y), where
 746  	// x ** frac(y) = exp(ln(x ** frac(y)) = exp(ln(x) * frac(y))
 747  	fracPartPow, err := d.Abs().Ln(-d.exp + int32(precision))
 748  	if err != nil {
 749  		return Decimal{}
 750  	}
 751  
 752  	fracPartPow = fracPartPow.Mul(expFracPart)
 753  
 754  	fracPartPow, err = fracPartPow.ExpTaylor(-d.exp + int32(precision))
 755  	if err != nil {
 756  		return Decimal{}
 757  	}
 758  
 759  	// Join integer and fractional part,
 760  	// base ** (expBase + expFrac) = base ** expBase * base ** expFrac
 761  	res := intPartPow.Mul(fracPartPow)
 762  
 763  	return res
 764  }
 765  
 766  // PowWithPrecision returns d to the power of d2.
 767  // Precision parameter specifies minimum precision of the result (digits after decimal point).
 768  // Returned decimal is not rounded to 'precision' places after decimal point.
 769  //
 770  // PowWithPrecision returns error when:
 771  //   - 0 ** 0 => undefined value
 772  //   - 0 ** y, where y < 0 => infinity
 773  //   - x ** y, where x < 0 and y is non-integer decimal => imaginary value
 774  //
 775  // Example:
 776  //
 777  //	d1 := decimal.NewFromFloat(4.0)
 778  //	d2 := decimal.NewFromFloat(4.0)
 779  //	res1, err := d1.PowWithPrecision(d2, 2)
 780  //	res1.String() // output: "256"
 781  //
 782  //	d3 := decimal.NewFromFloat(5.0)
 783  //	d4 := decimal.NewFromFloat(5.73)
 784  //	res2, err := d3.PowWithPrecision(d4, 5)
 785  //	res2.String() // output: "10118.080371595015625"
 786  //
 787  //	d5 := decimal.NewFromFloat(-3.0)
 788  //	d6 := decimal.NewFromFloat(-6.0)
 789  //	res3, err := d5.PowWithPrecision(d6, 10)
 790  //	res3.String() // output: "0.0013717421"
 791  func (d Decimal) PowWithPrecision(d2 Decimal, precision int32) (Decimal, error) {
 792  	baseSign := d.Sign()
 793  	expSign := d2.Sign()
 794  
 795  	if baseSign == 0 {
 796  		if expSign == 0 {
 797  			return Decimal{}, fmt.Errorf("cannot represent undefined value of 0**0")
 798  		}
 799  		if expSign == 1 {
 800  			return Decimal{zeroInt, 0}, nil
 801  		}
 802  		if expSign == -1 {
 803  			return Decimal{}, fmt.Errorf("cannot represent infinity value of 0 ** y, where y < 0")
 804  		}
 805  	}
 806  
 807  	if expSign == 0 {
 808  		return Decimal{oneInt, 0}, nil
 809  	}
 810  
 811  	// TODO: optimize extraction of fractional part
 812  	one := Decimal{oneInt, 0}
 813  	expIntPart, expFracPart := d2.QuoRem(one, 0)
 814  
 815  	if baseSign == -1 && !expFracPart.IsZero() {
 816  		return Decimal{}, fmt.Errorf("cannot represent imaginary value of x ** y, where x < 0 and y is non-integer decimal")
 817  	}
 818  
 819  	intPartPow, _ := d.powBigIntWithPrecision(expIntPart.value, precision)
 820  
 821  	// if exponent is an integer we don't need to calculate d1**frac(d2)
 822  	if expFracPart.value.Sign() == 0 {
 823  		return intPartPow, nil
 824  	}
 825  
 826  	// TODO: optimize NumDigits for more performant precision adjustment
 827  	digitsBase := d.NumDigits()
 828  	digitsExponent := d2.NumDigits()
 829  
 830  	if int32(digitsBase) > precision {
 831  		precision = int32(digitsBase)
 832  	}
 833  	if int32(digitsExponent) > precision {
 834  		precision += int32(digitsExponent)
 835  	}
 836  	// increase precision by 10 to compensate for errors in further calculations
 837  	precision += 10
 838  
 839  	// Calculate x ** frac(y), where
 840  	// x ** frac(y) = exp(ln(x ** frac(y)) = exp(ln(x) * frac(y))
 841  	fracPartPow, err := d.Abs().Ln(precision)
 842  	if err != nil {
 843  		return Decimal{}, err
 844  	}
 845  
 846  	fracPartPow = fracPartPow.Mul(expFracPart)
 847  
 848  	fracPartPow, err = fracPartPow.ExpTaylor(precision)
 849  	if err != nil {
 850  		return Decimal{}, err
 851  	}
 852  
 853  	// Join integer and fractional part,
 854  	// base ** (expBase + expFrac) = base ** expBase * base ** expFrac
 855  	res := intPartPow.Mul(fracPartPow)
 856  
 857  	return res, nil
 858  }
 859  
 860  // PowInt32 returns d to the power of exp, where exp is int32.
 861  // Only returns error when d and exp is 0, thus result is undefined.
 862  //
 863  // When exponent is negative the returned decimal will have maximum precision of PowPrecisionNegativeExponent places after decimal point.
 864  //
 865  // Example:
 866  //
 867  //	d1, err := decimal.NewFromFloat(4.0).PowInt32(4)
 868  //	d1.String() // output: "256"
 869  //
 870  //	d2, err := decimal.NewFromFloat(3.13).PowInt32(5)
 871  //	d2.String() // output: "300.4150512793"
 872  func (d Decimal) PowInt32(exp int32) (Decimal, error) {
 873  	if d.IsZero() && exp == 0 {
 874  		return Decimal{}, fmt.Errorf("cannot represent undefined value of 0**0")
 875  	}
 876  
 877  	isExpNeg := exp < 0
 878  	exp = abs(exp)
 879  
 880  	n, result := d, New(1, 0)
 881  
 882  	for exp > 0 {
 883  		if exp%2 == 1 {
 884  			result = result.Mul(n)
 885  		}
 886  		exp /= 2
 887  
 888  		if exp > 0 {
 889  			n = n.Mul(n)
 890  		}
 891  	}
 892  
 893  	if isExpNeg {
 894  		return New(1, 0).DivRound(result, int32(PowPrecisionNegativeExponent)), nil
 895  	}
 896  
 897  	return result, nil
 898  }
 899  
 900  // PowBigInt returns d to the power of exp, where exp is big.Int.
 901  // Only returns error when d and exp is 0, thus result is undefined.
 902  //
 903  // When exponent is negative the returned decimal will have maximum precision of PowPrecisionNegativeExponent places after decimal point.
 904  //
 905  // Example:
 906  //
 907  //	d1, err := decimal.NewFromFloat(3.0).PowBigInt(big.NewInt(3))
 908  //	d1.String() // output: "27"
 909  //
 910  //	d2, err := decimal.NewFromFloat(629.25).PowBigInt(big.NewInt(5))
 911  //	d2.String() // output: "98654323103449.5673828125"
 912  func (d Decimal) PowBigInt(exp *big.Int) (Decimal, error) {
 913  	return d.powBigIntWithPrecision(exp, int32(PowPrecisionNegativeExponent))
 914  }
 915  
 916  func (d Decimal) powBigIntWithPrecision(exp *big.Int, precision int32) (Decimal, error) {
 917  	if d.IsZero() && exp.Sign() == 0 {
 918  		return Decimal{}, fmt.Errorf("cannot represent undefined value of 0**0")
 919  	}
 920  
 921  	tmpExp := new(big.Int).Set(exp)
 922  	isExpNeg := exp.Sign() < 0
 923  
 924  	if isExpNeg {
 925  		tmpExp.Abs(tmpExp)
 926  	}
 927  
 928  	n, result := d, New(1, 0)
 929  
 930  	for tmpExp.Sign() > 0 {
 931  		if tmpExp.Bit(0) == 1 {
 932  			result = result.Mul(n)
 933  		}
 934  		tmpExp.Rsh(tmpExp, 1)
 935  
 936  		if tmpExp.Sign() > 0 {
 937  			n = n.Mul(n)
 938  		}
 939  	}
 940  
 941  	if isExpNeg {
 942  		return New(1, 0).DivRound(result, precision), nil
 943  	}
 944  
 945  	return result, nil
 946  }
 947  
 948  // ExpHullAbrham calculates the natural exponent of decimal (e to the power of d) using Hull-Abraham algorithm.
 949  // OverallPrecision argument specifies the overall precision of the result (integer part + decimal part).
 950  //
 951  // ExpHullAbrham is faster than ExpTaylor for small precision values, but it is much slower for large precision values.
 952  //
 953  // Example:
 954  //
 955  //	NewFromFloat(26.1).ExpHullAbrham(2).String()    // output: "220000000000"
 956  //	NewFromFloat(26.1).ExpHullAbrham(20).String()   // output: "216314672147.05767284"
 957  func (d Decimal) ExpHullAbrham(overallPrecision uint32) (Decimal, error) {
 958  	// Algorithm based on Variable precision exponential function.
 959  	// ACM Transactions on Mathematical Software by T. E. Hull & A. Abrham.
 960  	if d.IsZero() {
 961  		return Decimal{oneInt, 0}, nil
 962  	}
 963  
 964  	currentPrecision := overallPrecision
 965  
 966  	// Algorithm does not work if currentPrecision * 23 < |x|.
 967  	// Precision is automatically increased in such cases, so the value can be calculated precisely.
 968  	// If newly calculated precision is higher than ExpMaxIterations the currentPrecision will not be changed.
 969  	f := d.Abs().InexactFloat64()
 970  	if ncp := f / 23; ncp > float64(currentPrecision) && ncp < float64(ExpMaxIterations) {
 971  		currentPrecision = uint32(math.Ceil(ncp))
 972  	}
 973  
 974  	// fail if abs(d) beyond an over/underflow threshold
 975  	overflowThreshold := New(23*int64(currentPrecision), 0)
 976  	if d.Abs().Cmp(overflowThreshold) > 0 {
 977  		return Decimal{}, fmt.Errorf("over/underflow threshold, exp(x) cannot be calculated precisely")
 978  	}
 979  
 980  	// Return 1 if abs(d) small enough; this also avoids later over/underflow
 981  	overflowThreshold2 := New(9, -int32(currentPrecision)-1)
 982  	if d.Abs().Cmp(overflowThreshold2) <= 0 {
 983  		return Decimal{oneInt, d.exp}, nil
 984  	}
 985  
 986  	// t is the smallest integer >= 0 such that the corresponding abs(d/k) < 1
 987  	t := d.exp + int32(d.NumDigits()) // Add d.NumDigits because the paper assumes that d.value [0.1, 1)
 988  
 989  	if t < 0 {
 990  		t = 0
 991  	}
 992  
 993  	k := New(1, t)                                     // reduction factor
 994  	r := Decimal{new(big.Int).Set(d.value), d.exp - t} // reduced argument
 995  	p := int32(currentPrecision) + t + 2               // precision for calculating the sum
 996  
 997  	// Determine n, the number of therms for calculating sum
 998  	// use first Newton step (1.435p - 1.182) / log10(p/abs(r))
 999  	// for solving appropriate equation, along with directed
1000  	// roundings and simple rational bound for log10(p/abs(r))
1001  	rf := r.Abs().InexactFloat64()
1002  	pf := float64(p)
1003  	nf := math.Ceil((1.453*pf - 1.182) / math.Log10(pf/rf))
1004  	if nf > float64(ExpMaxIterations) || math.IsNaN(nf) {
1005  		return Decimal{}, fmt.Errorf("exact value cannot be calculated in <=ExpMaxIterations iterations")
1006  	}
1007  	n := int64(nf)
1008  
1009  	tmp := New(0, 0)
1010  	sum := New(1, 0)
1011  	one := New(1, 0)
1012  	for i := n - 1; i > 0; i-- {
1013  		tmp.value.SetInt64(i)
1014  		sum = sum.Mul(r.DivRound(tmp, p))
1015  		sum = sum.Add(one)
1016  	}
1017  
1018  	ki := k.IntPart()
1019  	res := New(1, 0)
1020  	for i := ki; i > 0; i-- {
1021  		res = res.Mul(sum)
1022  	}
1023  
1024  	resNumDigits := int32(res.NumDigits())
1025  
1026  	var roundDigits int32
1027  	if resNumDigits > abs(res.exp) {
1028  		roundDigits = int32(currentPrecision) - resNumDigits - res.exp
1029  	} else {
1030  		roundDigits = int32(currentPrecision)
1031  	}
1032  
1033  	res = res.Round(roundDigits)
1034  
1035  	return res, nil
1036  }
1037  
1038  // ExpTaylor calculates the natural exponent of decimal (e to the power of d) using Taylor series expansion.
1039  // Precision argument specifies how precise the result must be (number of digits after decimal point).
1040  // Negative precision is allowed.
1041  //
1042  // ExpTaylor is much faster for large precision values than ExpHullAbrham.
1043  //
1044  // Example:
1045  //
1046  //	d, err := NewFromFloat(26.1).ExpTaylor(2).String()
1047  //	d.String()  // output: "216314672147.06"
1048  //
1049  //	NewFromFloat(26.1).ExpTaylor(20).String()
1050  //	d.String()  // output: "216314672147.05767284062928674083"
1051  //
1052  //	NewFromFloat(26.1).ExpTaylor(-10).String()
1053  //	d.String()  // output: "220000000000"
1054  func (d Decimal) ExpTaylor(precision int32) (Decimal, error) {
1055  	// Note(mwoss): Implementation can be optimized by exclusively using big.Int API only
1056  	if d.IsZero() {
1057  		return Decimal{oneInt, 0}.Round(precision), nil
1058  	}
1059  
1060  	var epsilon Decimal
1061  	var divPrecision int32
1062  	if precision < 0 {
1063  		epsilon = New(1, -1)
1064  		divPrecision = 8
1065  	} else {
1066  		epsilon = New(1, -precision-1)
1067  		divPrecision = precision + 1
1068  	}
1069  
1070  	decAbs := d.Abs()
1071  	pow := d.Abs()
1072  	factorial := New(1, 0)
1073  
1074  	result := New(1, 0)
1075  
1076  	for i := int64(1); ; {
1077  		step := pow.DivRound(factorial, divPrecision)
1078  		result = result.Add(step)
1079  
1080  		// Stop Taylor series when current step is smaller than epsilon
1081  		if step.Cmp(epsilon) < 0 {
1082  			break
1083  		}
1084  
1085  		pow = pow.Mul(decAbs)
1086  
1087  		i++
1088  
1089  		// Calculate next factorial number or retrieve cached value
1090  		if len(factorials) >= int(i) && !factorials[i-1].IsZero() {
1091  			factorial = factorials[i-1]
1092  		} else {
1093  			// To avoid any race conditions, firstly the zero value is appended to a slice to create
1094  			// a spot for newly calculated factorial. After that, the zero value is replaced by calculated
1095  			// factorial using the index notation.
1096  			factorial = factorials[i-2].Mul(New(i, 0))
1097  			factorials = append(factorials, Zero)
1098  			factorials[i-1] = factorial
1099  		}
1100  	}
1101  
1102  	if d.Sign() < 0 {
1103  		result = New(1, 0).DivRound(result, precision+1)
1104  	}
1105  
1106  	result = result.Round(precision)
1107  	return result, nil
1108  }
1109  
1110  // Ln calculates natural logarithm of d.
1111  // Precision argument specifies how precise the result must be (number of digits after decimal point).
1112  // Negative precision is allowed.
1113  //
1114  // Example:
1115  //
1116  //	d1, err := NewFromFloat(13.3).Ln(2)
1117  //	d1.String()  // output: "2.59"
1118  //
1119  //	d2, err := NewFromFloat(579.161).Ln(10)
1120  //	d2.String()  // output: "6.3615805046"
1121  func (d Decimal) Ln(precision int32) (Decimal, error) {
1122  	// Algorithm based on The Use of Iteration Methods for Approximating the Natural Logarithm,
1123  	// James F. Epperson, The American Mathematical Monthly, Vol. 96, No. 9, November 1989, pp. 831-835.
1124  	if d.IsNegative() {
1125  		return Decimal{}, fmt.Errorf("cannot calculate natural logarithm for negative decimals")
1126  	}
1127  
1128  	if d.IsZero() {
1129  		return Decimal{}, fmt.Errorf("cannot represent natural logarithm of 0, result: -infinity")
1130  	}
1131  
1132  	calcPrecision := precision + 2
1133  	z := d.Copy()
1134  
1135  	var comp1, comp3, comp2, comp4, reduceAdjust Decimal
1136  	comp1 = z.Sub(Decimal{oneInt, 0})
1137  	comp3 = Decimal{oneInt, -1}
1138  
1139  	// for decimal in range [0.9, 1.1] where ln(d) is close to 0
1140  	usePowerSeries := false
1141  
1142  	if comp1.Abs().Cmp(comp3) <= 0 {
1143  		usePowerSeries = true
1144  	} else {
1145  		// reduce input decimal to range [0.1, 1)
1146  		expDelta := int32(z.NumDigits()) + z.exp
1147  		z.exp -= expDelta
1148  
1149  		// Input decimal was reduced by factor of 10^expDelta, thus we will need to add
1150  		// ln(10^expDelta) = expDelta * ln(10)
1151  		// to the result to compensate that
1152  		ln10 := ln10.withPrecision(calcPrecision)
1153  		reduceAdjust = NewFromInt32(expDelta)
1154  		reduceAdjust = reduceAdjust.Mul(ln10)
1155  
1156  		comp1 = z.Sub(Decimal{oneInt, 0})
1157  
1158  		if comp1.Abs().Cmp(comp3) <= 0 {
1159  			usePowerSeries = true
1160  		} else {
1161  			// initial estimate using floats
1162  			zFloat := z.InexactFloat64()
1163  			comp1 = NewFromFloat(math.Log(zFloat))
1164  		}
1165  	}
1166  
1167  	epsilon := Decimal{oneInt, -calcPrecision}
1168  
1169  	if usePowerSeries {
1170  		// Power Series - https://en.wikipedia.org/wiki/Logarithm#Power_series
1171  		// Calculating n-th term of formula: ln(z+1) = 2 sum [ 1 / (2n+1) * (z / (z+2))^(2n+1) ]
1172  		// until the difference between current and next term is smaller than epsilon.
1173  		// Coverage quite fast for decimals close to 1.0
1174  
1175  		// z + 2
1176  		comp2 = comp1.Add(Decimal{twoInt, 0})
1177  		// z / (z + 2)
1178  		comp3 = comp1.DivRound(comp2, calcPrecision)
1179  		// 2 * (z / (z + 2))
1180  		comp1 = comp3.Add(comp3)
1181  		comp2 = comp1.Copy()
1182  
1183  		for n := 1; ; n++ {
1184  			// 2 * (z / (z+2))^(2n+1)
1185  			comp2 = comp2.Mul(comp3).Mul(comp3)
1186  
1187  			// 1 / (2n+1) * 2 * (z / (z+2))^(2n+1)
1188  			comp4 = NewFromInt(int64(2*n + 1))
1189  			comp4 = comp2.DivRound(comp4, calcPrecision)
1190  
1191  			// comp1 = 2 sum [ 1 / (2n+1) * (z / (z+2))^(2n+1) ]
1192  			comp1 = comp1.Add(comp4)
1193  
1194  			if comp4.Abs().Cmp(epsilon) <= 0 {
1195  				break
1196  			}
1197  		}
1198  	} else {
1199  		// Halley's Iteration.
1200  		// Calculating n-th term of formula: a_(n+1) = a_n - 2 * (exp(a_n) - z) / (exp(a_n) + z),
1201  		// until the difference between current and next term is smaller than epsilon
1202  		var prevStep Decimal
1203  		maxIters := calcPrecision*2 + 10
1204  
1205  		for i := int32(0); i < maxIters; i++ {
1206  			// exp(a_n)
1207  			comp3, _ = comp1.ExpTaylor(calcPrecision)
1208  			// exp(a_n) - z
1209  			comp2 = comp3.Sub(z)
1210  			// 2 * (exp(a_n) - z)
1211  			comp2 = comp2.Add(comp2)
1212  			// exp(a_n) + z
1213  			comp4 = comp3.Add(z)
1214  			// 2 * (exp(a_n) - z) / (exp(a_n) + z)
1215  			comp3 = comp2.DivRound(comp4, calcPrecision)
1216  			// comp1 = a_(n+1) = a_n - 2 * (exp(a_n) - z) / (exp(a_n) + z)
1217  			comp1 = comp1.Sub(comp3)
1218  
1219  			if prevStep.Add(comp3).IsZero() {
1220  				// If iteration steps oscillate we should return early and prevent an infinity loop
1221  				// NOTE(mwoss): This should be quite a rare case, returning error is not necessary
1222  				break
1223  			}
1224  
1225  			if comp3.Abs().Cmp(epsilon) <= 0 {
1226  				break
1227  			}
1228  
1229  			prevStep = comp3
1230  		}
1231  	}
1232  
1233  	comp1 = comp1.Add(reduceAdjust)
1234  
1235  	return comp1.Round(precision), nil
1236  }
1237  
1238  // NumDigits returns the number of digits of the decimal coefficient (d.Value)
1239  func (d Decimal) NumDigits() int {
1240  	if d.value == nil {
1241  		return 1
1242  	}
1243  
1244  	if d.value.IsInt64() {
1245  		i64 := d.value.Int64()
1246  		// restrict fast path to integers with exact conversion to float64
1247  		if i64 <= (1<<53) && i64 >= -(1<<53) {
1248  			if i64 == 0 {
1249  				return 1
1250  			}
1251  			return int(math.Log10(math.Abs(float64(i64)))) + 1
1252  		}
1253  	}
1254  
1255  	estimatedNumDigits := int(float64(d.value.BitLen()) / math.Log2(10))
1256  
1257  	// estimatedNumDigits (lg10) may be off by 1, need to verify
1258  	digitsBigInt := big.NewInt(int64(estimatedNumDigits))
1259  	errorCorrectionUnit := digitsBigInt.Exp(tenInt, digitsBigInt, nil)
1260  
1261  	if d.value.CmpAbs(errorCorrectionUnit) >= 0 {
1262  		return estimatedNumDigits + 1
1263  	}
1264  
1265  	return estimatedNumDigits
1266  }
1267  
1268  // IsInteger returns true when decimal can be represented as an integer value, otherwise, it returns false.
1269  func (d Decimal) IsInteger() bool {
1270  	// The most typical case, all decimal with exponent higher or equal 0 can be represented as integer
1271  	if d.exp >= 0 {
1272  		return true
1273  	}
1274  	// When the exponent is negative we have to check every number after the decimal place
1275  	// If all of them are zeroes, we are sure that given decimal can be represented as an integer
1276  	var r big.Int
1277  	q := new(big.Int).Set(d.value)
1278  	for z := abs(d.exp); z > 0; z-- {
1279  		q.QuoRem(q, tenInt, &r)
1280  		if r.Cmp(zeroInt) != 0 {
1281  			return false
1282  		}
1283  	}
1284  	return true
1285  }
1286  
1287  // Abs calculates absolute value of any int32. Used for calculating absolute value of decimal's exponent.
1288  func abs(n int32) int32 {
1289  	if n < 0 {
1290  		return -n
1291  	}
1292  	return n
1293  }
1294  
1295  // Cmp compares the numbers represented by d and d2 and returns:
1296  //
1297  //	-1 if d <  d2
1298  //	 0 if d == d2
1299  //	+1 if d >  d2
1300  func (d Decimal) Cmp(d2 Decimal) int {
1301  	d.ensureInitialized()
1302  	d2.ensureInitialized()
1303  
1304  	if d.exp == d2.exp {
1305  		return d.value.Cmp(d2.value)
1306  	}
1307  
1308  	rd, rd2 := RescalePair(d, d2)
1309  
1310  	return rd.value.Cmp(rd2.value)
1311  }
1312  
1313  // Compare compares the numbers represented by d and d2 and returns:
1314  //
1315  //	-1 if d <  d2
1316  //	 0 if d == d2
1317  //	+1 if d >  d2
1318  func (d Decimal) Compare(d2 Decimal) int {
1319  	return d.Cmp(d2)
1320  }
1321  
1322  // Equal returns whether the numbers represented by d and d2 are equal.
1323  func (d Decimal) Equal(d2 Decimal) bool {
1324  	return d.Cmp(d2) == 0
1325  }
1326  
1327  // Deprecated: Equals is deprecated, please use Equal method instead.
1328  func (d Decimal) Equals(d2 Decimal) bool {
1329  	return d.Equal(d2)
1330  }
1331  
1332  // GreaterThan (GT) returns true when d is greater than d2.
1333  func (d Decimal) GreaterThan(d2 Decimal) bool {
1334  	return d.Cmp(d2) == 1
1335  }
1336  
1337  // GreaterThanOrEqual (GTE) returns true when d is greater than or equal to d2.
1338  func (d Decimal) GreaterThanOrEqual(d2 Decimal) bool {
1339  	cmp := d.Cmp(d2)
1340  	return cmp == 1 || cmp == 0
1341  }
1342  
1343  // LessThan (LT) returns true when d is less than d2.
1344  func (d Decimal) LessThan(d2 Decimal) bool {
1345  	return d.Cmp(d2) == -1
1346  }
1347  
1348  // LessThanOrEqual (LTE) returns true when d is less than or equal to d2.
1349  func (d Decimal) LessThanOrEqual(d2 Decimal) bool {
1350  	cmp := d.Cmp(d2)
1351  	return cmp == -1 || cmp == 0
1352  }
1353  
1354  // Sign returns:
1355  //
1356  //	-1 if d <  0
1357  //	 0 if d == 0
1358  //	+1 if d >  0
1359  func (d Decimal) Sign() int {
1360  	if d.value == nil {
1361  		return 0
1362  	}
1363  	return d.value.Sign()
1364  }
1365  
1366  // IsPositive return
1367  //
1368  //	true if d > 0
1369  //	false if d == 0
1370  //	false if d < 0
1371  func (d Decimal) IsPositive() bool {
1372  	return d.Sign() == 1
1373  }
1374  
1375  // IsNegative return
1376  //
1377  //	true if d < 0
1378  //	false if d == 0
1379  //	false if d > 0
1380  func (d Decimal) IsNegative() bool {
1381  	return d.Sign() == -1
1382  }
1383  
1384  // IsZero return
1385  //
1386  //	true if d == 0
1387  //	false if d > 0
1388  //	false if d < 0
1389  func (d Decimal) IsZero() bool {
1390  	return d.Sign() == 0
1391  }
1392  
1393  // Exponent returns the exponent, or scale component of the decimal.
1394  func (d Decimal) Exponent() int32 {
1395  	return d.exp
1396  }
1397  
1398  // Coefficient returns the coefficient of the decimal. It is scaled by 10^Exponent()
1399  func (d Decimal) Coefficient() *big.Int {
1400  	d.ensureInitialized()
1401  	// we copy the coefficient so that mutating the result does not mutate the Decimal.
1402  	return new(big.Int).Set(d.value)
1403  }
1404  
1405  // CoefficientInt64 returns the coefficient of the decimal as int64. It is scaled by 10^Exponent()
1406  // If coefficient cannot be represented in an int64, the result will be undefined.
1407  func (d Decimal) CoefficientInt64() int64 {
1408  	d.ensureInitialized()
1409  	return d.value.Int64()
1410  }
1411  
1412  // IntPart returns the integer component of the decimal.
1413  func (d Decimal) IntPart() int64 {
1414  	scaledD := d.rescale(0)
1415  	return scaledD.value.Int64()
1416  }
1417  
1418  // BigInt returns integer component of the decimal as a BigInt.
1419  func (d Decimal) BigInt() *big.Int {
1420  	scaledD := d.rescale(0)
1421  	return scaledD.value
1422  }
1423  
1424  // BigFloat returns decimal as BigFloat.
1425  // Be aware that casting decimal to BigFloat might cause a loss of precision.
1426  func (d Decimal) BigFloat() *big.Float {
1427  	f := &big.Float{}
1428  	f.SetString(d.String())
1429  	return f
1430  }
1431  
1432  // Rat returns a rational number representation of the decimal.
1433  func (d Decimal) Rat() *big.Rat {
1434  	d.ensureInitialized()
1435  	if d.exp <= 0 {
1436  		// NOTE(vadim): must negate after casting to prevent int32 overflow
1437  		denom := new(big.Int).Exp(tenInt, big.NewInt(-int64(d.exp)), nil)
1438  		return new(big.Rat).SetFrac(d.value, denom)
1439  	}
1440  
1441  	mul := new(big.Int).Exp(tenInt, big.NewInt(int64(d.exp)), nil)
1442  	num := new(big.Int).Mul(d.value, mul)
1443  	return new(big.Rat).SetFrac(num, oneInt)
1444  }
1445  
1446  // Float64 returns the nearest float64 value for d and a bool indicating
1447  // whether f represents d exactly.
1448  // For more details, see the documentation for big.Rat.Float64
1449  func (d Decimal) Float64() (f float64, exact bool) {
1450  	return d.Rat().Float64()
1451  }
1452  
1453  // InexactFloat64 returns the nearest float64 value for d.
1454  // It doesn't indicate if the returned value represents d exactly.
1455  func (d Decimal) InexactFloat64() float64 {
1456  	f, _ := d.Float64()
1457  	return f
1458  }
1459  
1460  // String returns the string representation of the decimal
1461  // with the fixed point.
1462  //
1463  // Example:
1464  //
1465  //	d := New(-12345, -3)
1466  //	println(d.String())
1467  //
1468  // Output:
1469  //
1470  //	-12.345
1471  func (d Decimal) String() string {
1472  	return d.string(true)
1473  }
1474  
1475  // StringFixed returns a rounded fixed-point string with places digits after
1476  // the decimal point.
1477  //
1478  // Example:
1479  //
1480  //	NewFromFloat(0).StringFixed(2) // output: "0.00"
1481  //	NewFromFloat(0).StringFixed(0) // output: "0"
1482  //	NewFromFloat(5.45).StringFixed(0) // output: "5"
1483  //	NewFromFloat(5.45).StringFixed(1) // output: "5.5"
1484  //	NewFromFloat(5.45).StringFixed(2) // output: "5.45"
1485  //	NewFromFloat(5.45).StringFixed(3) // output: "5.450"
1486  //	NewFromFloat(545).StringFixed(-1) // output: "550"
1487  func (d Decimal) StringFixed(places int32) string {
1488  	rounded := d.Round(places)
1489  	return rounded.string(false)
1490  }
1491  
1492  // StringFixedBank returns a banker rounded fixed-point string with places digits
1493  // after the decimal point.
1494  //
1495  // Example:
1496  //
1497  //	NewFromFloat(0).StringFixedBank(2) // output: "0.00"
1498  //	NewFromFloat(0).StringFixedBank(0) // output: "0"
1499  //	NewFromFloat(5.45).StringFixedBank(0) // output: "5"
1500  //	NewFromFloat(5.45).StringFixedBank(1) // output: "5.4"
1501  //	NewFromFloat(5.45).StringFixedBank(2) // output: "5.45"
1502  //	NewFromFloat(5.45).StringFixedBank(3) // output: "5.450"
1503  //	NewFromFloat(545).StringFixedBank(-1) // output: "540"
1504  func (d Decimal) StringFixedBank(places int32) string {
1505  	rounded := d.RoundBank(places)
1506  	return rounded.string(false)
1507  }
1508  
1509  // StringFixedCash returns a Swedish/Cash rounded fixed-point string. For
1510  // more details see the documentation at function RoundCash.
1511  func (d Decimal) StringFixedCash(interval uint8) string {
1512  	rounded := d.RoundCash(interval)
1513  	return rounded.string(false)
1514  }
1515  
1516  // Round rounds the decimal to places decimal places.
1517  // If places < 0, it will round the integer part to the nearest 10^(-places).
1518  //
1519  // Example:
1520  //
1521  //	NewFromFloat(5.45).Round(1).String() // output: "5.5"
1522  //	NewFromFloat(545).Round(-1).String() // output: "550"
1523  func (d Decimal) Round(places int32) Decimal {
1524  	if d.exp == -places {
1525  		return d
1526  	}
1527  	// truncate to places + 1
1528  	ret := d.rescale(-places - 1)
1529  
1530  	// add sign(d) * 0.5
1531  	if ret.value.Sign() < 0 {
1532  		ret.value.Sub(ret.value, fiveInt)
1533  	} else {
1534  		ret.value.Add(ret.value, fiveInt)
1535  	}
1536  
1537  	// floor for positive numbers, ceil for negative numbers
1538  	_, m := ret.value.DivMod(ret.value, tenInt, new(big.Int))
1539  	ret.exp++
1540  	if ret.value.Sign() < 0 && m.Cmp(zeroInt) != 0 {
1541  		ret.value.Add(ret.value, oneInt)
1542  	}
1543  
1544  	return ret
1545  }
1546  
1547  // RoundCeil rounds the decimal towards +infinity.
1548  //
1549  // Example:
1550  //
1551  //	NewFromFloat(545).RoundCeil(-2).String()   // output: "600"
1552  //	NewFromFloat(500).RoundCeil(-2).String()   // output: "500"
1553  //	NewFromFloat(1.1001).RoundCeil(2).String() // output: "1.11"
1554  //	NewFromFloat(-1.454).RoundCeil(1).String() // output: "-1.4"
1555  func (d Decimal) RoundCeil(places int32) Decimal {
1556  	if d.exp >= -places {
1557  		return d
1558  	}
1559  
1560  	rescaled := d.rescale(-places)
1561  	if d.Equal(rescaled) {
1562  		return d
1563  	}
1564  
1565  	if d.value.Sign() > 0 {
1566  		rescaled.value.Add(rescaled.value, oneInt)
1567  	}
1568  
1569  	return rescaled
1570  }
1571  
1572  // RoundFloor rounds the decimal towards -infinity.
1573  //
1574  // Example:
1575  //
1576  //	NewFromFloat(545).RoundFloor(-2).String()   // output: "500"
1577  //	NewFromFloat(-500).RoundFloor(-2).String()   // output: "-500"
1578  //	NewFromFloat(1.1001).RoundFloor(2).String() // output: "1.1"
1579  //	NewFromFloat(-1.454).RoundFloor(1).String() // output: "-1.5"
1580  func (d Decimal) RoundFloor(places int32) Decimal {
1581  	if d.exp >= -places {
1582  		return d
1583  	}
1584  
1585  	rescaled := d.rescale(-places)
1586  	if d.Equal(rescaled) {
1587  		return d
1588  	}
1589  
1590  	if d.value.Sign() < 0 {
1591  		rescaled.value.Sub(rescaled.value, oneInt)
1592  	}
1593  
1594  	return rescaled
1595  }
1596  
1597  // RoundUp rounds the decimal away from zero.
1598  //
1599  // Example:
1600  //
1601  //	NewFromFloat(545).RoundUp(-2).String()   // output: "600"
1602  //	NewFromFloat(500).RoundUp(-2).String()   // output: "500"
1603  //	NewFromFloat(1.1001).RoundUp(2).String() // output: "1.11"
1604  //	NewFromFloat(-1.454).RoundUp(1).String() // output: "-1.5"
1605  func (d Decimal) RoundUp(places int32) Decimal {
1606  	if d.exp >= -places {
1607  		return d
1608  	}
1609  
1610  	rescaled := d.rescale(-places)
1611  	if d.Equal(rescaled) {
1612  		return d
1613  	}
1614  
1615  	if d.value.Sign() > 0 {
1616  		rescaled.value.Add(rescaled.value, oneInt)
1617  	} else if d.value.Sign() < 0 {
1618  		rescaled.value.Sub(rescaled.value, oneInt)
1619  	}
1620  
1621  	return rescaled
1622  }
1623  
1624  // RoundDown rounds the decimal towards zero.
1625  //
1626  // Example:
1627  //
1628  //	NewFromFloat(545).RoundDown(-2).String()   // output: "500"
1629  //	NewFromFloat(-500).RoundDown(-2).String()   // output: "-500"
1630  //	NewFromFloat(1.1001).RoundDown(2).String() // output: "1.1"
1631  //	NewFromFloat(-1.454).RoundDown(1).String() // output: "-1.4"
1632  func (d Decimal) RoundDown(places int32) Decimal {
1633  	if d.exp >= -places {
1634  		return d
1635  	}
1636  
1637  	rescaled := d.rescale(-places)
1638  	if d.Equal(rescaled) {
1639  		return d
1640  	}
1641  	return rescaled
1642  }
1643  
1644  // RoundBank rounds the decimal to places decimal places.
1645  // If the final digit to round is equidistant from the nearest two integers the
1646  // rounded value is taken as the even number
1647  //
1648  // If places < 0, it will round the integer part to the nearest 10^(-places).
1649  //
1650  // Examples:
1651  //
1652  //	NewFromFloat(5.45).RoundBank(1).String() // output: "5.4"
1653  //	NewFromFloat(545).RoundBank(-1).String() // output: "540"
1654  //	NewFromFloat(5.46).RoundBank(1).String() // output: "5.5"
1655  //	NewFromFloat(546).RoundBank(-1).String() // output: "550"
1656  //	NewFromFloat(5.55).RoundBank(1).String() // output: "5.6"
1657  //	NewFromFloat(555).RoundBank(-1).String() // output: "560"
1658  func (d Decimal) RoundBank(places int32) Decimal {
1659  
1660  	round := d.Round(places)
1661  	remainder := d.Sub(round).Abs()
1662  
1663  	half := New(5, -places-1)
1664  	if remainder.Cmp(half) == 0 && round.value.Bit(0) != 0 {
1665  		if round.value.Sign() < 0 {
1666  			round.value.Add(round.value, oneInt)
1667  		} else {
1668  			round.value.Sub(round.value, oneInt)
1669  		}
1670  	}
1671  
1672  	return round
1673  }
1674  
1675  // RoundCash aka Cash/Penny/öre rounding rounds decimal to a specific
1676  // interval. The amount payable for a cash transaction is rounded to the nearest
1677  // multiple of the minimum currency unit available. The following intervals are
1678  // available: 5, 10, 25, 50 and 100; any other number throws a panic.
1679  //
1680  //	  5:   5 cent rounding 3.43 => 3.45
1681  //	 10:  10 cent rounding 3.45 => 3.50 (5 gets rounded up)
1682  //	 25:  25 cent rounding 3.41 => 3.50
1683  //	 50:  50 cent rounding 3.75 => 4.00
1684  //	100: 100 cent rounding 3.50 => 4.00
1685  //
1686  // For more details: https://en.wikipedia.org/wiki/Cash_rounding
1687  func (d Decimal) RoundCash(interval uint8) Decimal {
1688  	var iVal *big.Int
1689  	switch interval {
1690  	case 5:
1691  		iVal = twentyInt
1692  	case 10:
1693  		iVal = tenInt
1694  	case 25:
1695  		iVal = fourInt
1696  	case 50:
1697  		iVal = twoInt
1698  	case 100:
1699  		iVal = oneInt
1700  	default:
1701  		panic(fmt.Sprintf("Decimal does not support this Cash rounding interval `%d`. Supported: 5, 10, 25, 50, 100", interval))
1702  	}
1703  	dVal := Decimal{
1704  		value: iVal,
1705  	}
1706  
1707  	// TODO: optimize those calculations to reduce the high allocations (~29 allocs).
1708  	return d.Mul(dVal).Round(0).Div(dVal).Truncate(2)
1709  }
1710  
1711  // Floor returns the nearest integer value less than or equal to d.
1712  func (d Decimal) Floor() Decimal {
1713  	d.ensureInitialized()
1714  
1715  	if d.exp >= 0 {
1716  		return d
1717  	}
1718  
1719  	exp := big.NewInt(10)
1720  
1721  	// NOTE(vadim): must negate after casting to prevent int32 overflow
1722  	exp.Exp(exp, big.NewInt(-int64(d.exp)), nil)
1723  
1724  	z := new(big.Int).Div(d.value, exp)
1725  	return Decimal{value: z, exp: 0}
1726  }
1727  
1728  // Ceil returns the nearest integer value greater than or equal to d.
1729  func (d Decimal) Ceil() Decimal {
1730  	d.ensureInitialized()
1731  
1732  	if d.exp >= 0 {
1733  		return d
1734  	}
1735  
1736  	exp := big.NewInt(10)
1737  
1738  	// NOTE(vadim): must negate after casting to prevent int32 overflow
1739  	exp.Exp(exp, big.NewInt(-int64(d.exp)), nil)
1740  
1741  	z, m := new(big.Int).DivMod(d.value, exp, new(big.Int))
1742  	if m.Cmp(zeroInt) != 0 {
1743  		z.Add(z, oneInt)
1744  	}
1745  	return Decimal{value: z, exp: 0}
1746  }
1747  
1748  // Truncate truncates off digits from the number, without rounding.
1749  //
1750  // NOTE: precision is the last digit that will not be truncated (must be >= 0).
1751  //
1752  // Example:
1753  //
1754  //	decimal.NewFromString("123.456").Truncate(2).String() // "123.45"
1755  func (d Decimal) Truncate(precision int32) Decimal {
1756  	d.ensureInitialized()
1757  	if precision >= 0 && -precision > d.exp {
1758  		return d.rescale(-precision)
1759  	}
1760  	return d
1761  }
1762  
1763  // UnmarshalJSON implements the json.Unmarshaler interface.
1764  func (d *Decimal) UnmarshalJSON(decimalBytes []byte) error {
1765  	if string(decimalBytes) == "null" {
1766  		return nil
1767  	}
1768  
1769  	str, err := unquoteIfQuoted(decimalBytes)
1770  	if err != nil {
1771  		return fmt.Errorf("error decoding string '%s': %s", decimalBytes, err)
1772  	}
1773  
1774  	decimal, err := NewFromString(str)
1775  	*d = decimal
1776  	if err != nil {
1777  		return fmt.Errorf("error decoding string '%s': %s", str, err)
1778  	}
1779  	return nil
1780  }
1781  
1782  // MarshalJSON implements the json.Marshaler interface.
1783  func (d Decimal) MarshalJSON() ([]byte, error) {
1784  	var str string
1785  	if MarshalJSONWithoutQuotes {
1786  		str = d.String()
1787  	} else {
1788  		str = "\"" + d.String() + "\""
1789  	}
1790  	return []byte(str), nil
1791  }
1792  
1793  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. As a string representation
1794  // is already used when encoding to text, this method stores that string as []byte
1795  func (d *Decimal) UnmarshalBinary(data []byte) error {
1796  	// Verify we have at least 4 bytes for the exponent. The GOB encoded value
1797  	// may be empty.
1798  	if len(data) < 4 {
1799  		return fmt.Errorf("error decoding binary %v: expected at least 4 bytes, got %d", data, len(data))
1800  	}
1801  
1802  	// Extract the exponent
1803  	d.exp = int32(binary.BigEndian.Uint32(data[:4]))
1804  
1805  	// Extract the value
1806  	d.value = new(big.Int)
1807  	if err := d.value.GobDecode(data[4:]); err != nil {
1808  		return fmt.Errorf("error decoding binary %v: %s", data, err)
1809  	}
1810  
1811  	return nil
1812  }
1813  
1814  // MarshalBinary implements the encoding.BinaryMarshaler interface.
1815  func (d Decimal) MarshalBinary() (data []byte, err error) {
1816  	// exp is written first, but encode value first to know output size
1817  	var valueData []byte
1818  	if valueData, err = d.value.GobEncode(); err != nil {
1819  		return nil, err
1820  	}
1821  
1822  	// Write the exponent in front, since it's a fixed size
1823  	expData := make([]byte, 4, len(valueData)+4)
1824  	binary.BigEndian.PutUint32(expData, uint32(d.exp))
1825  
1826  	// Return the byte array
1827  	return append(expData, valueData...), nil
1828  }
1829  
1830  // Scan implements the sql.Scanner interface for database deserialization.
1831  func (d *Decimal) Scan(value interface{}) error {
1832  	// first try to see if the data is stored in database as a Numeric datatype
1833  	switch v := value.(type) {
1834  
1835  	case float32:
1836  		*d = NewFromFloat(float64(v))
1837  		return nil
1838  
1839  	case float64:
1840  		// numeric in sqlite3 sends us float64
1841  		*d = NewFromFloat(v)
1842  		return nil
1843  
1844  	case int64:
1845  		// at least in sqlite3 when the value is 0 in db, the data is sent
1846  		// to us as an int64 instead of a float64 ...
1847  		*d = New(v, 0)
1848  		return nil
1849  
1850  	case uint64:
1851  		// while clickhouse may send 0 in db as uint64
1852  		*d = NewFromUint64(v)
1853  		return nil
1854  
1855  	default:
1856  		// default is trying to interpret value stored as string
1857  		str, err := unquoteIfQuoted(v)
1858  		if err != nil {
1859  			return err
1860  		}
1861  		*d, err = NewFromString(str)
1862  		return err
1863  	}
1864  }
1865  
1866  // Value implements the driver.Valuer interface for database serialization.
1867  func (d Decimal) Value() (driver.Value, error) {
1868  	return d.String(), nil
1869  }
1870  
1871  // UnmarshalText implements the encoding.TextUnmarshaler interface for XML
1872  // deserialization.
1873  func (d *Decimal) UnmarshalText(text []byte) error {
1874  	str := string(text)
1875  
1876  	dec, err := NewFromString(str)
1877  	*d = dec
1878  	if err != nil {
1879  		return fmt.Errorf("error decoding string '%s': %s", str, err)
1880  	}
1881  
1882  	return nil
1883  }
1884  
1885  // MarshalText implements the encoding.TextMarshaler interface for XML
1886  // serialization.
1887  func (d Decimal) MarshalText() (text []byte, err error) {
1888  	return []byte(d.String()), nil
1889  }
1890  
1891  // GobEncode implements the gob.GobEncoder interface for gob serialization.
1892  func (d Decimal) GobEncode() ([]byte, error) {
1893  	return d.MarshalBinary()
1894  }
1895  
1896  // GobDecode implements the gob.GobDecoder interface for gob serialization.
1897  func (d *Decimal) GobDecode(data []byte) error {
1898  	return d.UnmarshalBinary(data)
1899  }
1900  
1901  // StringScaled first scales the decimal then calls .String() on it.
1902  //
1903  // Deprecated: buggy and unintuitive. Use StringFixed instead.
1904  func (d Decimal) StringScaled(exp int32) string {
1905  	return d.rescale(exp).String()
1906  }
1907  
1908  func (d Decimal) string(trimTrailingZeros bool) string {
1909  	if d.exp >= 0 {
1910  		return d.rescale(0).value.String()
1911  	}
1912  
1913  	abs := new(big.Int).Abs(d.value)
1914  	str := abs.String()
1915  
1916  	var intPart, fractionalPart string
1917  
1918  	// NOTE(vadim): this cast to int will cause bugs if d.exp == INT_MIN
1919  	// and you are on a 32-bit machine. Won't fix this super-edge case.
1920  	dExpInt := int(d.exp)
1921  	if len(str) > -dExpInt {
1922  		intPart = str[:len(str)+dExpInt]
1923  		fractionalPart = str[len(str)+dExpInt:]
1924  	} else {
1925  		intPart = "0"
1926  
1927  		num0s := -dExpInt - len(str)
1928  		fractionalPart = strings.Repeat("0", num0s) + str
1929  	}
1930  
1931  	if trimTrailingZeros {
1932  		i := len(fractionalPart) - 1
1933  		for ; i >= 0; i-- {
1934  			if fractionalPart[i] != '0' {
1935  				break
1936  			}
1937  		}
1938  		fractionalPart = fractionalPart[:i+1]
1939  	}
1940  
1941  	number := intPart
1942  	if len(fractionalPart) > 0 {
1943  		number += "." + fractionalPart
1944  	}
1945  
1946  	if d.value.Sign() < 0 {
1947  		return "-" + number
1948  	}
1949  
1950  	return number
1951  }
1952  
1953  func (d *Decimal) ensureInitialized() {
1954  	if d.value == nil {
1955  		d.value = new(big.Int)
1956  	}
1957  }
1958  
1959  // Min returns the smallest Decimal that was passed in the arguments.
1960  //
1961  // To call this function with an array, you must do:
1962  //
1963  //	Min(arr[0], arr[1:]...)
1964  //
1965  // This makes it harder to accidentally call Min with 0 arguments.
1966  func Min(first Decimal, rest ...Decimal) Decimal {
1967  	ans := first
1968  	for _, item := range rest {
1969  		if item.Cmp(ans) < 0 {
1970  			ans = item
1971  		}
1972  	}
1973  	return ans
1974  }
1975  
1976  // Max returns the largest Decimal that was passed in the arguments.
1977  //
1978  // To call this function with an array, you must do:
1979  //
1980  //	Max(arr[0], arr[1:]...)
1981  //
1982  // This makes it harder to accidentally call Max with 0 arguments.
1983  func Max(first Decimal, rest ...Decimal) Decimal {
1984  	ans := first
1985  	for _, item := range rest {
1986  		if item.Cmp(ans) > 0 {
1987  			ans = item
1988  		}
1989  	}
1990  	return ans
1991  }
1992  
1993  // Sum returns the combined total of the provided first and rest Decimals
1994  func Sum(first Decimal, rest ...Decimal) Decimal {
1995  	total := first
1996  	for _, item := range rest {
1997  		total = total.Add(item)
1998  	}
1999  
2000  	return total
2001  }
2002  
2003  // Avg returns the average value of the provided first and rest Decimals
2004  func Avg(first Decimal, rest ...Decimal) Decimal {
2005  	count := New(int64(len(rest)+1), 0)
2006  	sum := Sum(first, rest...)
2007  	return sum.Div(count)
2008  }
2009  
2010  // RescalePair rescales two decimals to common exponential value (minimal exp of both decimals)
2011  func RescalePair(d1 Decimal, d2 Decimal) (Decimal, Decimal) {
2012  	d1.ensureInitialized()
2013  	d2.ensureInitialized()
2014  
2015  	if d1.exp < d2.exp {
2016  		return d1, d2.rescale(d1.exp)
2017  	} else if d1.exp > d2.exp {
2018  		return d1.rescale(d2.exp), d2
2019  	}
2020  
2021  	return d1, d2
2022  }
2023  
2024  func unquoteIfQuoted(value interface{}) (string, error) {
2025  	var bytes []byte
2026  
2027  	switch v := value.(type) {
2028  	case string:
2029  		bytes = []byte(v)
2030  	case []byte:
2031  		bytes = v
2032  	default:
2033  		return "", fmt.Errorf("could not convert value '%+v' to byte array of type '%T'", value, value)
2034  	}
2035  
2036  	// If the amount is quoted, strip the quotes
2037  	if len(bytes) > 2 && bytes[0] == '"' && bytes[len(bytes)-1] == '"' {
2038  		bytes = bytes[1 : len(bytes)-1]
2039  	}
2040  	return string(bytes), nil
2041  }
2042  
2043  // NullDecimal represents a nullable decimal with compatibility for
2044  // scanning null values from the database.
2045  type NullDecimal struct {
2046  	Decimal Decimal
2047  	Valid   bool
2048  }
2049  
2050  func NewNullDecimal(d Decimal) NullDecimal {
2051  	return NullDecimal{
2052  		Decimal: d,
2053  		Valid:   true,
2054  	}
2055  }
2056  
2057  // Scan implements the sql.Scanner interface for database deserialization.
2058  func (d *NullDecimal) Scan(value interface{}) error {
2059  	if value == nil {
2060  		d.Valid = false
2061  		return nil
2062  	}
2063  	d.Valid = true
2064  	return d.Decimal.Scan(value)
2065  }
2066  
2067  // Value implements the driver.Valuer interface for database serialization.
2068  func (d NullDecimal) Value() (driver.Value, error) {
2069  	if !d.Valid {
2070  		return nil, nil
2071  	}
2072  	return d.Decimal.Value()
2073  }
2074  
2075  // UnmarshalJSON implements the json.Unmarshaler interface.
2076  func (d *NullDecimal) UnmarshalJSON(decimalBytes []byte) error {
2077  	if string(decimalBytes) == "null" {
2078  		d.Valid = false
2079  		return nil
2080  	}
2081  	d.Valid = true
2082  	return d.Decimal.UnmarshalJSON(decimalBytes)
2083  }
2084  
2085  // MarshalJSON implements the json.Marshaler interface.
2086  func (d NullDecimal) MarshalJSON() ([]byte, error) {
2087  	if !d.Valid {
2088  		return []byte("null"), nil
2089  	}
2090  	return d.Decimal.MarshalJSON()
2091  }
2092  
2093  // UnmarshalText implements the encoding.TextUnmarshaler interface for XML
2094  // deserialization
2095  func (d *NullDecimal) UnmarshalText(text []byte) error {
2096  	str := string(text)
2097  
2098  	// check for empty XML or XML without body e.g., <tag></tag>
2099  	if str == "" {
2100  		d.Valid = false
2101  		return nil
2102  	}
2103  	if err := d.Decimal.UnmarshalText(text); err != nil {
2104  		d.Valid = false
2105  		return err
2106  	}
2107  	d.Valid = true
2108  	return nil
2109  }
2110  
2111  // MarshalText implements the encoding.TextMarshaler interface for XML
2112  // serialization.
2113  func (d NullDecimal) MarshalText() (text []byte, err error) {
2114  	if !d.Valid {
2115  		return []byte{}, nil
2116  	}
2117  	return d.Decimal.MarshalText()
2118  }
2119  
2120  // Trig functions
2121  
2122  // Atan returns the arctangent, in radians, of x.
2123  func (d Decimal) Atan() Decimal {
2124  	if d.Equal(NewFromFloat(0.0)) {
2125  		return d
2126  	}
2127  	if d.GreaterThan(NewFromFloat(0.0)) {
2128  		return d.satan()
2129  	}
2130  	return d.Neg().satan().Neg()
2131  }
2132  
2133  func (d Decimal) xatan() Decimal {
2134  	P0 := NewFromFloat(-8.750608600031904122785e-01)
2135  	P1 := NewFromFloat(-1.615753718733365076637e+01)
2136  	P2 := NewFromFloat(-7.500855792314704667340e+01)
2137  	P3 := NewFromFloat(-1.228866684490136173410e+02)
2138  	P4 := NewFromFloat(-6.485021904942025371773e+01)
2139  	Q0 := NewFromFloat(2.485846490142306297962e+01)
2140  	Q1 := NewFromFloat(1.650270098316988542046e+02)
2141  	Q2 := NewFromFloat(4.328810604912902668951e+02)
2142  	Q3 := NewFromFloat(4.853903996359136964868e+02)
2143  	Q4 := NewFromFloat(1.945506571482613964425e+02)
2144  	z := d.Mul(d)
2145  	b1 := P0.Mul(z).Add(P1).Mul(z).Add(P2).Mul(z).Add(P3).Mul(z).Add(P4).Mul(z)
2146  	b2 := z.Add(Q0).Mul(z).Add(Q1).Mul(z).Add(Q2).Mul(z).Add(Q3).Mul(z).Add(Q4)
2147  	z = b1.Div(b2)
2148  	z = d.Mul(z).Add(d)
2149  	return z
2150  }
2151  
2152  // satan reduces its argument (known to be positive)
2153  // to the range [0, 0.66] and calls xatan.
2154  func (d Decimal) satan() Decimal {
2155  	Morebits := NewFromFloat(6.123233995736765886130e-17) // pi/2 = PIO2 + Morebits
2156  	Tan3pio8 := NewFromFloat(2.41421356237309504880)      // tan(3*pi/8)
2157  	pi := NewFromFloat(3.14159265358979323846264338327950288419716939937510582097494459)
2158  
2159  	if d.LessThanOrEqual(NewFromFloat(0.66)) {
2160  		return d.xatan()
2161  	}
2162  	if d.GreaterThan(Tan3pio8) {
2163  		return pi.Div(NewFromFloat(2.0)).Sub(NewFromFloat(1.0).Div(d).xatan()).Add(Morebits)
2164  	}
2165  	return pi.Div(NewFromFloat(4.0)).Add((d.Sub(NewFromFloat(1.0)).Div(d.Add(NewFromFloat(1.0)))).xatan()).Add(NewFromFloat(0.5).Mul(Morebits))
2166  }
2167  
2168  // sin coefficients
2169  var _sin = [...]Decimal{
2170  	NewFromFloat(1.58962301576546568060e-10), // 0x3de5d8fd1fd19ccd
2171  	NewFromFloat(-2.50507477628578072866e-8), // 0xbe5ae5e5a9291f5d
2172  	NewFromFloat(2.75573136213857245213e-6),  // 0x3ec71de3567d48a1
2173  	NewFromFloat(-1.98412698295895385996e-4), // 0xbf2a01a019bfdf03
2174  	NewFromFloat(8.33333333332211858878e-3),  // 0x3f8111111110f7d0
2175  	NewFromFloat(-1.66666666666666307295e-1), // 0xbfc5555555555548
2176  }
2177  
2178  // Sin returns the sine of the radian argument x.
2179  func (d Decimal) Sin() Decimal {
2180  	PI4A := NewFromFloat(7.85398125648498535156e-1)                             // 0x3fe921fb40000000, Pi/4 split into three parts
2181  	PI4B := NewFromFloat(3.77489470793079817668e-8)                             // 0x3e64442d00000000,
2182  	PI4C := NewFromFloat(2.69515142907905952645e-15)                            // 0x3ce8469898cc5170,
2183  	M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
2184  
2185  	if d.Equal(NewFromFloat(0.0)) {
2186  		return d
2187  	}
2188  	// make argument positive but save the sign
2189  	sign := false
2190  	if d.LessThan(NewFromFloat(0.0)) {
2191  		d = d.Neg()
2192  		sign = true
2193  	}
2194  
2195  	j := d.Mul(M4PI).IntPart()    // integer part of x/(Pi/4), as integer for tests on the phase angle
2196  	y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
2197  
2198  	// map zeros to origin
2199  	if j&1 == 1 {
2200  		j++
2201  		y = y.Add(NewFromFloat(1.0))
2202  	}
2203  	j &= 7 // octant modulo 2Pi radians (360 degrees)
2204  	// reflect in x axis
2205  	if j > 3 {
2206  		sign = !sign
2207  		j -= 4
2208  	}
2209  	z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
2210  	zz := z.Mul(z)
2211  
2212  	if j == 1 || j == 2 {
2213  		w := zz.Mul(zz).Mul(_cos[0].Mul(zz).Add(_cos[1]).Mul(zz).Add(_cos[2]).Mul(zz).Add(_cos[3]).Mul(zz).Add(_cos[4]).Mul(zz).Add(_cos[5]))
2214  		y = NewFromFloat(1.0).Sub(NewFromFloat(0.5).Mul(zz)).Add(w)
2215  	} else {
2216  		y = z.Add(z.Mul(zz).Mul(_sin[0].Mul(zz).Add(_sin[1]).Mul(zz).Add(_sin[2]).Mul(zz).Add(_sin[3]).Mul(zz).Add(_sin[4]).Mul(zz).Add(_sin[5])))
2217  	}
2218  	if sign {
2219  		y = y.Neg()
2220  	}
2221  	return y
2222  }
2223  
2224  // cos coefficients
2225  var _cos = [...]Decimal{
2226  	NewFromFloat(-1.13585365213876817300e-11), // 0xbda8fa49a0861a9b
2227  	NewFromFloat(2.08757008419747316778e-9),   // 0x3e21ee9d7b4e3f05
2228  	NewFromFloat(-2.75573141792967388112e-7),  // 0xbe927e4f7eac4bc6
2229  	NewFromFloat(2.48015872888517045348e-5),   // 0x3efa01a019c844f5
2230  	NewFromFloat(-1.38888888888730564116e-3),  // 0xbf56c16c16c14f91
2231  	NewFromFloat(4.16666666666665929218e-2),   // 0x3fa555555555554b
2232  }
2233  
2234  // Cos returns the cosine of the radian argument x.
2235  func (d Decimal) Cos() Decimal {
2236  
2237  	PI4A := NewFromFloat(7.85398125648498535156e-1)                             // 0x3fe921fb40000000, Pi/4 split into three parts
2238  	PI4B := NewFromFloat(3.77489470793079817668e-8)                             // 0x3e64442d00000000,
2239  	PI4C := NewFromFloat(2.69515142907905952645e-15)                            // 0x3ce8469898cc5170,
2240  	M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
2241  
2242  	// make argument positive
2243  	sign := false
2244  	if d.LessThan(NewFromFloat(0.0)) {
2245  		d = d.Neg()
2246  	}
2247  
2248  	j := d.Mul(M4PI).IntPart()    // integer part of x/(Pi/4), as integer for tests on the phase angle
2249  	y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
2250  
2251  	// map zeros to origin
2252  	if j&1 == 1 {
2253  		j++
2254  		y = y.Add(NewFromFloat(1.0))
2255  	}
2256  	j &= 7 // octant modulo 2Pi radians (360 degrees)
2257  	// reflect in x axis
2258  	if j > 3 {
2259  		sign = !sign
2260  		j -= 4
2261  	}
2262  	if j > 1 {
2263  		sign = !sign
2264  	}
2265  
2266  	z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
2267  	zz := z.Mul(z)
2268  
2269  	if j == 1 || j == 2 {
2270  		y = z.Add(z.Mul(zz).Mul(_sin[0].Mul(zz).Add(_sin[1]).Mul(zz).Add(_sin[2]).Mul(zz).Add(_sin[3]).Mul(zz).Add(_sin[4]).Mul(zz).Add(_sin[5])))
2271  	} else {
2272  		w := zz.Mul(zz).Mul(_cos[0].Mul(zz).Add(_cos[1]).Mul(zz).Add(_cos[2]).Mul(zz).Add(_cos[3]).Mul(zz).Add(_cos[4]).Mul(zz).Add(_cos[5]))
2273  		y = NewFromFloat(1.0).Sub(NewFromFloat(0.5).Mul(zz)).Add(w)
2274  	}
2275  	if sign {
2276  		y = y.Neg()
2277  	}
2278  	return y
2279  }
2280  
2281  var _tanP = [...]Decimal{
2282  	NewFromFloat(-1.30936939181383777646e+4), // 0xc0c992d8d24f3f38
2283  	NewFromFloat(1.15351664838587416140e+6),  // 0x413199eca5fc9ddd
2284  	NewFromFloat(-1.79565251976484877988e+7), // 0xc1711fead3299176
2285  }
2286  var _tanQ = [...]Decimal{
2287  	NewFromFloat(1.00000000000000000000e+0),
2288  	NewFromFloat(1.36812963470692954678e+4),  //0x40cab8a5eeb36572
2289  	NewFromFloat(-1.32089234440210967447e+6), //0xc13427bc582abc96
2290  	NewFromFloat(2.50083801823357915839e+7),  //0x4177d98fc2ead8ef
2291  	NewFromFloat(-5.38695755929454629881e+7), //0xc189afe03cbe5a31
2292  }
2293  
2294  // Tan returns the tangent of the radian argument x.
2295  func (d Decimal) Tan() Decimal {
2296  
2297  	PI4A := NewFromFloat(7.85398125648498535156e-1)                             // 0x3fe921fb40000000, Pi/4 split into three parts
2298  	PI4B := NewFromFloat(3.77489470793079817668e-8)                             // 0x3e64442d00000000,
2299  	PI4C := NewFromFloat(2.69515142907905952645e-15)                            // 0x3ce8469898cc5170,
2300  	M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
2301  
2302  	if d.Equal(NewFromFloat(0.0)) {
2303  		return d
2304  	}
2305  
2306  	// make argument positive but save the sign
2307  	sign := false
2308  	if d.LessThan(NewFromFloat(0.0)) {
2309  		d = d.Neg()
2310  		sign = true
2311  	}
2312  
2313  	j := d.Mul(M4PI).IntPart()    // integer part of x/(Pi/4), as integer for tests on the phase angle
2314  	y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
2315  
2316  	// map zeros to origin
2317  	if j&1 == 1 {
2318  		j++
2319  		y = y.Add(NewFromFloat(1.0))
2320  	}
2321  
2322  	z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
2323  	zz := z.Mul(z)
2324  
2325  	if zz.GreaterThan(NewFromFloat(1e-14)) {
2326  		w := zz.Mul(_tanP[0].Mul(zz).Add(_tanP[1]).Mul(zz).Add(_tanP[2]))
2327  		x := zz.Add(_tanQ[1]).Mul(zz).Add(_tanQ[2]).Mul(zz).Add(_tanQ[3]).Mul(zz).Add(_tanQ[4])
2328  		y = z.Add(z.Mul(w.Div(x)))
2329  	} else {
2330  		y = z
2331  	}
2332  	if j&2 == 2 {
2333  		y = NewFromFloat(-1.0).Div(y)
2334  	}
2335  	if sign {
2336  		y = y.Neg()
2337  	}
2338  	return y
2339  }
2340