...

Source file src/github.com/shopspring/decimal/decimal.go

Documentation: github.com/shopspring/decimal

     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  

View as plain text