github.com/godaddy-x/freego@v1.0.156/utils/decimal/decimal.go (about)

     1  // Package decimal implements an arbitrary precision fixed-point decimal.
     2  //
     3  // To use as part of a struct:
     4  //
     5  //     type Struct struct {
     6  //         Number Decimal
     7  //     }
     8  //
     9  // The zero-value of a Decimal is 0, as you would expect.
    10  //
    11  // The best way to create a new Decimal is to use decimal.NewFromString, ex:
    12  //
    13  //     n, err := decimal.NewFromString("-123.4567")
    14  //     n.String() // output: "-123.4567"
    15  //
    16  // NOTE: This can "only" represent numbers with a maximum of 2^31 digits
    17  // after the decimal point.
    18  package decimal
    19  
    20  import (
    21  	"database/sql/driver"
    22  	"encoding/binary"
    23  	"fmt"
    24  	"math"
    25  	"math/big"
    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  //
    45  var DivisionPrecision = 16
    46  
    47  // MarshalJSONWithoutQuotes should be set to true if you want the decimal to
    48  // be JSON marshaled as a number, instead of as a string.
    49  // WARNING: this is dangerous for decimals with many digits, since many JSON
    50  // unmarshallers (ex: Javascript's) will unmarshal JSON numbers to IEEE 754
    51  // double-precision floating point numbers, which means you can potentially
    52  // silently lose precision.
    53  var MarshalJSONWithoutQuotes = false
    54  
    55  // Zero constant, to make computations faster.
    56  var Zero = New(0, 1)
    57  
    58  // fiveDec used in Cash Rounding
    59  var fiveDec = New(5, 0)
    60  
    61  var zeroInt = big.NewInt(0)
    62  var oneInt = big.NewInt(1)
    63  var twoInt = big.NewInt(2)
    64  var fourInt = big.NewInt(4)
    65  var fiveInt = big.NewInt(5)
    66  var tenInt = big.NewInt(10)
    67  var twentyInt = big.NewInt(20)
    68  
    69  // Decimal represents a fixed-point decimal. It is immutable.
    70  // number = value * 10 ^ exp
    71  type Decimal struct {
    72  	value *big.Int
    73  
    74  	// NOTE(vadim): this must be an int32, because we cast it to float64 during
    75  	// calculations. If exp is 64 bit, we might lose precision.
    76  	// If we cared about being able to represent every possible decimal, we
    77  	// could make exp a *big.Int but it would hurt performance and numbers
    78  	// like that are unrealistic.
    79  	exp int32
    80  }
    81  
    82  // New returns a new fixed-point decimal, value * 10 ^ exp.
    83  func New(value int64, exp int32) Decimal {
    84  	return Decimal{
    85  		value: big.NewInt(value),
    86  		exp:   exp,
    87  	}
    88  }
    89  
    90  // NewFromBigInt returns a new Decimal from a big.Int, value * 10 ^ exp
    91  func NewFromBigInt(value *big.Int, exp int32) Decimal {
    92  	return Decimal{
    93  		value: big.NewInt(0).Set(value),
    94  		exp:   exp,
    95  	}
    96  }
    97  
    98  // NewFromString returns a new Decimal from a string representation.
    99  //
   100  // Example:
   101  //
   102  //     d, err := NewFromString("-123.45")
   103  //     d2, err := NewFromString(".0001")
   104  //
   105  func NewFromString(value string) (Decimal, error) {
   106  	originalInput := value
   107  	var intString string
   108  	var exp int64
   109  
   110  	// Check if number is using scientific notation
   111  	eIndex := strings.IndexAny(value, "Ee")
   112  	if eIndex != -1 {
   113  		expInt, err := strconv.ParseInt(value[eIndex+1:], 10, 32)
   114  		if err != nil {
   115  			if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
   116  				return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", value)
   117  			}
   118  			return Decimal{}, fmt.Errorf("can't convert %s to decimal: exponent is not numeric", value)
   119  		}
   120  		value = value[:eIndex]
   121  		exp = expInt
   122  	}
   123  
   124  	parts := strings.Split(value, ".")
   125  	if len(parts) == 1 {
   126  		// There is no decimal point, we can just parse the original string as
   127  		// an int
   128  		intString = value
   129  	} else if len(parts) == 2 {
   130  		// strip the insignificant digits for more accurate comparisons.
   131  		decimalPart := strings.TrimRight(parts[1], "0")
   132  		intString = parts[0] + decimalPart
   133  		expInt := -len(decimalPart)
   134  		exp += int64(expInt)
   135  	} else {
   136  		return Decimal{}, fmt.Errorf("can't convert %s to decimal: too many .s", value)
   137  	}
   138  
   139  	dValue := new(big.Int)
   140  	_, ok := dValue.SetString(intString, 10)
   141  	if !ok {
   142  		return Decimal{}, fmt.Errorf("can't convert %s to decimal", value)
   143  	}
   144  
   145  	if exp < math.MinInt32 || exp > math.MaxInt32 {
   146  		// NOTE(vadim): I doubt a string could realistically be this long
   147  		return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", originalInput)
   148  	}
   149  
   150  	return Decimal{
   151  		value: dValue,
   152  		exp:   int32(exp),
   153  	}, nil
   154  }
   155  
   156  // RequireFromString returns a new Decimal from a string representation
   157  // or panics if NewFromString would have returned an error.
   158  //
   159  // Example:
   160  //
   161  //     d := RequireFromString("-123.45")
   162  //     d2 := RequireFromString(".0001")
   163  //
   164  func RequireFromString(value string) Decimal {
   165  	dec, err := NewFromString(value)
   166  	if err != nil {
   167  		panic(err)
   168  	}
   169  	return dec
   170  }
   171  
   172  // NewFromFloat converts a float64 to Decimal.
   173  //
   174  // The converted number will contain the number of significant digits that can be
   175  // represented in a float with reliable roundtrip.
   176  // This is typically 15 digits, but may be more in some cases.
   177  // See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.
   178  //
   179  // For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.
   180  //
   181  // NOTE: this will panic on NaN, +/-inf
   182  func NewFromFloat(value float64) Decimal {
   183  	if value == 0 {
   184  		return New(0, 0)
   185  	}
   186  	return newFromFloat(value, math.Float64bits(value), &float64info)
   187  }
   188  
   189  // NewFromFloat converts a float32 to Decimal.
   190  //
   191  // The converted number will contain the number of significant digits that can be
   192  // represented in a float with reliable roundtrip.
   193  // This is typically 6-8 digits depending on the input.
   194  // See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.
   195  //
   196  // For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.
   197  //
   198  // NOTE: this will panic on NaN, +/-inf
   199  func NewFromFloat32(value float32) Decimal {
   200  	if value == 0 {
   201  		return New(0, 0)
   202  	}
   203  	// XOR is workaround for https://github.com/golang/go/issues/26285
   204  	a := math.Float32bits(value) ^ 0x80808080
   205  	return newFromFloat(float64(value), uint64(a)^0x80808080, &float32info)
   206  }
   207  
   208  func newFromFloat(val float64, bits uint64, flt *floatInfo) Decimal {
   209  	if math.IsNaN(val) || math.IsInf(val, 0) {
   210  		panic(fmt.Sprintf("Cannot create a Decimal from %v", val))
   211  	}
   212  	exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
   213  	mant := bits & (uint64(1)<<flt.mantbits - 1)
   214  
   215  	switch exp {
   216  	case 0:
   217  		// denormalized
   218  		exp++
   219  
   220  	default:
   221  		// add implicit top bit
   222  		mant |= uint64(1) << flt.mantbits
   223  	}
   224  	exp += flt.bias
   225  
   226  	var d decimal
   227  	d.Assign(mant)
   228  	d.Shift(exp - int(flt.mantbits))
   229  	d.neg = bits>>(flt.expbits+flt.mantbits) != 0
   230  
   231  	roundShortest(&d, mant, exp, flt)
   232  	// If less than 19 digits, we can do calculation in an int64.
   233  	if d.nd < 19 {
   234  		tmp := int64(0)
   235  		m := int64(1)
   236  		for i := d.nd - 1; i >= 0; i-- {
   237  			tmp += m * int64(d.d[i]-'0')
   238  			m *= 10
   239  		}
   240  		if d.neg {
   241  			tmp *= -1
   242  		}
   243  		return Decimal{value: big.NewInt(tmp), exp: int32(d.dp) - int32(d.nd)}
   244  	}
   245  	dValue := new(big.Int)
   246  	dValue, ok := dValue.SetString(string(d.d[:d.nd]), 10)
   247  	if ok {
   248  		return Decimal{value: dValue, exp: int32(d.dp) - int32(d.nd)}
   249  	}
   250  
   251  	return NewFromFloatWithExponent(val, int32(d.dp)-int32(d.nd))
   252  }
   253  
   254  // NewFromFloatWithExponent converts a float64 to Decimal, with an arbitrary
   255  // number of fractional digits.
   256  //
   257  // Example:
   258  //
   259  //     NewFromFloatWithExponent(123.456, -2).String() // output: "123.46"
   260  //
   261  func NewFromFloatWithExponent(value float64, exp int32) Decimal {
   262  	if math.IsNaN(value) || math.IsInf(value, 0) {
   263  		panic(fmt.Sprintf("Cannot create a Decimal from %v", value))
   264  	}
   265  
   266  	bits := math.Float64bits(value)
   267  	mant := bits & (1<<52 - 1)
   268  	exp2 := int32((bits >> 52) & (1<<11 - 1))
   269  	sign := bits >> 63
   270  
   271  	if exp2 == 0 {
   272  		// specials
   273  		if mant == 0 {
   274  			return Decimal{}
   275  		} else {
   276  			// subnormal
   277  			exp2++
   278  		}
   279  	} else {
   280  		// normal
   281  		mant |= 1 << 52
   282  	}
   283  
   284  	exp2 -= 1023 + 52
   285  
   286  	// normalizing base-2 values
   287  	for mant&1 == 0 {
   288  		mant = mant >> 1
   289  		exp2++
   290  	}
   291  
   292  	// maximum number of fractional base-10 digits to represent 2^N exactly cannot be more than -N if N<0
   293  	if exp < 0 && exp < exp2 {
   294  		if exp2 < 0 {
   295  			exp = exp2
   296  		} else {
   297  			exp = 0
   298  		}
   299  	}
   300  
   301  	// representing 10^M * 2^N as 5^M * 2^(M+N)
   302  	exp2 -= exp
   303  
   304  	temp := big.NewInt(1)
   305  	dMant := big.NewInt(int64(mant))
   306  
   307  	// applying 5^M
   308  	if exp > 0 {
   309  		temp = temp.SetInt64(int64(exp))
   310  		temp = temp.Exp(fiveInt, temp, nil)
   311  	} else if exp < 0 {
   312  		temp = temp.SetInt64(-int64(exp))
   313  		temp = temp.Exp(fiveInt, temp, nil)
   314  		dMant = dMant.Mul(dMant, temp)
   315  		temp = temp.SetUint64(1)
   316  	}
   317  
   318  	// applying 2^(M+N)
   319  	if exp2 > 0 {
   320  		dMant = dMant.Lsh(dMant, uint(exp2))
   321  	} else if exp2 < 0 {
   322  		temp = temp.Lsh(temp, uint(-exp2))
   323  	}
   324  
   325  	// rounding and downscaling
   326  	if exp > 0 || exp2 < 0 {
   327  		halfDown := new(big.Int).Rsh(temp, 1)
   328  		dMant = dMant.Add(dMant, halfDown)
   329  		dMant = dMant.Quo(dMant, temp)
   330  	}
   331  
   332  	if sign == 1 {
   333  		dMant = dMant.Neg(dMant)
   334  	}
   335  
   336  	return Decimal{
   337  		value: dMant,
   338  		exp:   exp,
   339  	}
   340  }
   341  
   342  // rescale returns a rescaled version of the decimal. Returned
   343  // decimal may be less precise if the given exponent is bigger
   344  // than the initial exponent of the Decimal.
   345  // NOTE: this will truncate, NOT round
   346  //
   347  // Example:
   348  //
   349  // 	d := New(12345, -4)
   350  //	d2 := d.rescale(-1)
   351  //	d3 := d2.rescale(-4)
   352  //	println(d1)
   353  //	println(d2)
   354  //	println(d3)
   355  //
   356  // Output:
   357  //
   358  //	1.2345
   359  //	1.2
   360  //	1.2000
   361  //
   362  func (d Decimal) rescale(exp int32) Decimal {
   363  	d.ensureInitialized()
   364  	// NOTE(vadim): must convert exps to float64 before - to prevent overflow
   365  	diff := math.Abs(float64(exp) - float64(d.exp))
   366  	value := new(big.Int).Set(d.value)
   367  
   368  	expScale := new(big.Int).Exp(tenInt, big.NewInt(int64(diff)), nil)
   369  	if exp > d.exp {
   370  		value = value.Quo(value, expScale)
   371  	} else if exp < d.exp {
   372  		value = value.Mul(value, expScale)
   373  	}
   374  
   375  	return Decimal{
   376  		value: value,
   377  		exp:   exp,
   378  	}
   379  }
   380  
   381  // Abs returns the absolute value of the decimal.
   382  func (d Decimal) Abs() Decimal {
   383  	d.ensureInitialized()
   384  	d2Value := new(big.Int).Abs(d.value)
   385  	return Decimal{
   386  		value: d2Value,
   387  		exp:   d.exp,
   388  	}
   389  }
   390  
   391  // Add returns d + d2.
   392  func (d Decimal) Add(d2 Decimal) Decimal {
   393  	baseScale := min(d.exp, d2.exp)
   394  	rd := d.rescale(baseScale)
   395  	rd2 := d2.rescale(baseScale)
   396  
   397  	d3Value := new(big.Int).Add(rd.value, rd2.value)
   398  	return Decimal{
   399  		value: d3Value,
   400  		exp:   baseScale,
   401  	}
   402  }
   403  
   404  // Sub returns d - d2.
   405  func (d Decimal) Sub(d2 Decimal) Decimal {
   406  	baseScale := min(d.exp, d2.exp)
   407  	rd := d.rescale(baseScale)
   408  	rd2 := d2.rescale(baseScale)
   409  
   410  	d3Value := new(big.Int).Sub(rd.value, rd2.value)
   411  	return Decimal{
   412  		value: d3Value,
   413  		exp:   baseScale,
   414  	}
   415  }
   416  
   417  // Neg returns -d.
   418  func (d Decimal) Neg() Decimal {
   419  	d.ensureInitialized()
   420  	val := new(big.Int).Neg(d.value)
   421  	return Decimal{
   422  		value: val,
   423  		exp:   d.exp,
   424  	}
   425  }
   426  
   427  // Mul returns d * d2.
   428  func (d Decimal) Mul(d2 Decimal) Decimal {
   429  	d.ensureInitialized()
   430  	d2.ensureInitialized()
   431  
   432  	expInt64 := int64(d.exp) + int64(d2.exp)
   433  	if expInt64 > math.MaxInt32 || expInt64 < math.MinInt32 {
   434  		// NOTE(vadim): better to panic than give incorrect results, as
   435  		// Decimals are usually used for money
   436  		panic(fmt.Sprintf("exponent %v overflows an int32!", expInt64))
   437  	}
   438  
   439  	d3Value := new(big.Int).Mul(d.value, d2.value)
   440  	return Decimal{
   441  		value: d3Value,
   442  		exp:   int32(expInt64),
   443  	}
   444  }
   445  
   446  // Shift shifts the decimal in base 10.
   447  // It shifts left when shift is positive and right if shift is negative.
   448  // In simpler terms, the given value for shift is added to the exponent
   449  // of the decimal.
   450  func (d Decimal) Shift(shift int32) Decimal {
   451  	d.ensureInitialized()
   452  	return Decimal{
   453  		value: new(big.Int).Set(d.value),
   454  		exp:   d.exp + shift,
   455  	}
   456  }
   457  
   458  // Div returns d / d2. If it doesn't divide exactly, the result will have
   459  // DivisionPrecision digits after the decimal point.
   460  func (d Decimal) Div(d2 Decimal) Decimal {
   461  	return d.DivRound(d2, int32(DivisionPrecision))
   462  }
   463  
   464  // QuoRem does divsion with remainder
   465  // d.QuoRem(d2,precision) returns quotient q and remainder r such that
   466  //   d = d2 * q + r, q an integer multiple of 10^(-precision)
   467  //   0 <= r < abs(d2) * 10 ^(-precision) if d>=0
   468  //   0 >= r > -abs(d2) * 10 ^(-precision) if d<0
   469  // Note that precision<0 is allowed as input.
   470  func (d Decimal) QuoRem(d2 Decimal, precision int32) (Decimal, Decimal) {
   471  	d.ensureInitialized()
   472  	d2.ensureInitialized()
   473  	if d2.value.Sign() == 0 {
   474  		panic("decimal division by 0")
   475  	}
   476  	scale := -precision
   477  	e := int64(d.exp - d2.exp - scale)
   478  	if e > math.MaxInt32 || e < math.MinInt32 {
   479  		panic("overflow in decimal QuoRem")
   480  	}
   481  	var aa, bb, expo big.Int
   482  	var scalerest int32
   483  	// d = a 10^ea
   484  	// d2 = b 10^eb
   485  	if e < 0 {
   486  		aa = *d.value
   487  		expo.SetInt64(-e)
   488  		bb.Exp(tenInt, &expo, nil)
   489  		bb.Mul(d2.value, &bb)
   490  		scalerest = d.exp
   491  		// now aa = a
   492  		//     bb = b 10^(scale + eb - ea)
   493  	} else {
   494  		expo.SetInt64(e)
   495  		aa.Exp(tenInt, &expo, nil)
   496  		aa.Mul(d.value, &aa)
   497  		bb = *d2.value
   498  		scalerest = scale + d2.exp
   499  		// now aa = a ^ (ea - eb - scale)
   500  		//     bb = b
   501  	}
   502  	var q, r big.Int
   503  	q.QuoRem(&aa, &bb, &r)
   504  	dq := Decimal{value: &q, exp: scale}
   505  	dr := Decimal{value: &r, exp: scalerest}
   506  	return dq, dr
   507  }
   508  
   509  // DivRound divides and rounds to a given precision
   510  // i.e. to an integer multiple of 10^(-precision)
   511  //   for a positive quotient digit 5 is rounded up, away from 0
   512  //   if the quotient is negative then digit 5 is rounded down, away from 0
   513  // Note that precision<0 is allowed as input.
   514  func (d Decimal) DivRound(d2 Decimal, precision int32) Decimal {
   515  	// QuoRem already checks initialization
   516  	q, r := d.QuoRem(d2, precision)
   517  	// the actual rounding decision is based on comparing r*10^precision and d2/2
   518  	// instead compare 2 r 10 ^precision and d2
   519  	var rv2 big.Int
   520  	rv2.Abs(r.value)
   521  	rv2.Lsh(&rv2, 1)
   522  	// now rv2 = abs(r.value) * 2
   523  	r2 := Decimal{value: &rv2, exp: r.exp + precision}
   524  	// r2 is now 2 * r * 10 ^ precision
   525  	var c = r2.Cmp(d2.Abs())
   526  
   527  	if c < 0 {
   528  		return q
   529  	}
   530  
   531  	if d.value.Sign()*d2.value.Sign() < 0 {
   532  		return q.Sub(New(1, -precision))
   533  	}
   534  
   535  	return q.Add(New(1, -precision))
   536  }
   537  
   538  // Mod returns d % d2.
   539  func (d Decimal) Mod(d2 Decimal) Decimal {
   540  	quo := d.Div(d2).Truncate(0)
   541  	return d.Sub(d2.Mul(quo))
   542  }
   543  
   544  // Pow returns d to the power d2
   545  func (d Decimal) Pow(d2 Decimal) Decimal {
   546  	var temp Decimal
   547  	if d2.IntPart() == 0 {
   548  		return NewFromFloat(1)
   549  	}
   550  	temp = d.Pow(d2.Div(NewFromFloat(2)))
   551  	if d2.IntPart()%2 == 0 {
   552  		return temp.Mul(temp)
   553  	}
   554  	if d2.IntPart() > 0 {
   555  		return temp.Mul(temp).Mul(d)
   556  	}
   557  	return temp.Mul(temp).Div(d)
   558  }
   559  
   560  // Cmp compares the numbers represented by d and d2 and returns:
   561  //
   562  //     -1 if d <  d2
   563  //      0 if d == d2
   564  //     +1 if d >  d2
   565  //
   566  func (d Decimal) Cmp(d2 Decimal) int {
   567  	d.ensureInitialized()
   568  	d2.ensureInitialized()
   569  
   570  	if d.exp == d2.exp {
   571  		return d.value.Cmp(d2.value)
   572  	}
   573  
   574  	baseExp := min(d.exp, d2.exp)
   575  	rd := d.rescale(baseExp)
   576  	rd2 := d2.rescale(baseExp)
   577  
   578  	return rd.value.Cmp(rd2.value)
   579  }
   580  
   581  // Equal returns whether the numbers represented by d and d2 are equal.
   582  func (d Decimal) Equal(d2 Decimal) bool {
   583  	return d.Cmp(d2) == 0
   584  }
   585  
   586  // Equals is deprecated, please use Equal method instead
   587  func (d Decimal) Equals(d2 Decimal) bool {
   588  	return d.Equal(d2)
   589  }
   590  
   591  // GreaterThan (GT) returns true when d is greater than d2.
   592  func (d Decimal) GreaterThan(d2 Decimal) bool {
   593  	return d.Cmp(d2) == 1
   594  }
   595  
   596  // GreaterThanOrEqual (GTE) returns true when d is greater than or equal to d2.
   597  func (d Decimal) GreaterThanOrEqual(d2 Decimal) bool {
   598  	cmp := d.Cmp(d2)
   599  	return cmp == 1 || cmp == 0
   600  }
   601  
   602  // LessThan (LT) returns true when d is less than d2.
   603  func (d Decimal) LessThan(d2 Decimal) bool {
   604  	return d.Cmp(d2) == -1
   605  }
   606  
   607  // LessThanOrEqual (LTE) returns true when d is less than or equal to d2.
   608  func (d Decimal) LessThanOrEqual(d2 Decimal) bool {
   609  	cmp := d.Cmp(d2)
   610  	return cmp == -1 || cmp == 0
   611  }
   612  
   613  // Sign returns:
   614  //
   615  //	-1 if d <  0
   616  //	 0 if d == 0
   617  //	+1 if d >  0
   618  //
   619  func (d Decimal) Sign() int {
   620  	if d.value == nil {
   621  		return 0
   622  	}
   623  	return d.value.Sign()
   624  }
   625  
   626  // IsPositive return
   627  //
   628  //	true if d > 0
   629  //	false if d == 0
   630  //	false if d < 0
   631  func (d Decimal) IsPositive() bool {
   632  	return d.Sign() == 1
   633  }
   634  
   635  // IsNegative return
   636  //
   637  //	true if d < 0
   638  //	false if d == 0
   639  //	false if d > 0
   640  func (d Decimal) IsNegative() bool {
   641  	return d.Sign() == -1
   642  }
   643  
   644  // IsZero return
   645  //
   646  //	true if d == 0
   647  //	false if d > 0
   648  //	false if d < 0
   649  func (d Decimal) IsZero() bool {
   650  	return d.Sign() == 0
   651  }
   652  
   653  // Exponent returns the exponent, or scale component of the decimal.
   654  func (d Decimal) Exponent() int32 {
   655  	return d.exp
   656  }
   657  
   658  // Coefficient returns the coefficient of the decimal.  It is scaled by 10^Exponent()
   659  func (d Decimal) Coefficient() *big.Int {
   660  	// we copy the coefficient so that mutating the result does not mutate the
   661  	// Decimal.
   662  	return big.NewInt(0).Set(d.value)
   663  }
   664  
   665  // IntPart returns the integer component of the decimal.
   666  func (d Decimal) IntPart() int64 {
   667  	scaledD := d.rescale(0)
   668  	return scaledD.value.Int64()
   669  }
   670  
   671  // Rat returns a rational number representation of the decimal.
   672  func (d Decimal) Rat() *big.Rat {
   673  	d.ensureInitialized()
   674  	if d.exp <= 0 {
   675  		// NOTE(vadim): must negate after casting to prevent int32 overflow
   676  		denom := new(big.Int).Exp(tenInt, big.NewInt(-int64(d.exp)), nil)
   677  		return new(big.Rat).SetFrac(d.value, denom)
   678  	}
   679  
   680  	mul := new(big.Int).Exp(tenInt, big.NewInt(int64(d.exp)), nil)
   681  	num := new(big.Int).Mul(d.value, mul)
   682  	return new(big.Rat).SetFrac(num, oneInt)
   683  }
   684  
   685  // Float64 returns the nearest float64 value for d and a bool indicating
   686  // whether f represents d exactly.
   687  // For more details, see the documentation for big.Rat.Float64
   688  func (d Decimal) Float64() (f float64, exact bool) {
   689  	return d.Rat().Float64()
   690  }
   691  
   692  // String returns the string representation of the decimal
   693  // with the fixed point.
   694  //
   695  // Example:
   696  //
   697  //     d := New(-12345, -3)
   698  //     println(d.String())
   699  //
   700  // Output:
   701  //
   702  //     -12.345
   703  //
   704  func (d Decimal) String() string {
   705  	return d.string(true)
   706  }
   707  
   708  // StringFixed returns a rounded fixed-point string with places digits after
   709  // the decimal point.
   710  //
   711  // Example:
   712  //
   713  // 	   NewFromFloat(0).StringFixed(2) // output: "0.00"
   714  // 	   NewFromFloat(0).StringFixed(0) // output: "0"
   715  // 	   NewFromFloat(5.45).StringFixed(0) // output: "5"
   716  // 	   NewFromFloat(5.45).StringFixed(1) // output: "5.5"
   717  // 	   NewFromFloat(5.45).StringFixed(2) // output: "5.45"
   718  // 	   NewFromFloat(5.45).StringFixed(3) // output: "5.450"
   719  // 	   NewFromFloat(545).StringFixed(-1) // output: "550"
   720  //
   721  func (d Decimal) StringFixed(places int32) string {
   722  	rounded := d.Round(places)
   723  	return rounded.string(false)
   724  }
   725  
   726  // StringFixedBank returns a banker rounded fixed-point string with places digits
   727  // after the decimal point.
   728  //
   729  // Example:
   730  //
   731  // 	   NewFromFloat(0).StringFixed(2) // output: "0.00"
   732  // 	   NewFromFloat(0).StringFixed(0) // output: "0"
   733  // 	   NewFromFloat(5.45).StringFixed(0) // output: "5"
   734  // 	   NewFromFloat(5.45).StringFixed(1) // output: "5.4"
   735  // 	   NewFromFloat(5.45).StringFixed(2) // output: "5.45"
   736  // 	   NewFromFloat(5.45).StringFixed(3) // output: "5.450"
   737  // 	   NewFromFloat(545).StringFixed(-1) // output: "550"
   738  //
   739  func (d Decimal) StringFixedBank(places int32) string {
   740  	rounded := d.RoundBank(places)
   741  	return rounded.string(false)
   742  }
   743  
   744  // StringFixedCash returns a Swedish/Cash rounded fixed-point string. For
   745  // more details see the documentation at function RoundCash.
   746  func (d Decimal) StringFixedCash(interval uint8) string {
   747  	rounded := d.RoundCash(interval)
   748  	return rounded.string(false)
   749  }
   750  
   751  // Round rounds the decimal to places decimal places.
   752  // If places < 0, it will round the integer part to the nearest 10^(-places).
   753  //
   754  // Example:
   755  //
   756  // 	   NewFromFloat(5.45).Round(1).String() // output: "5.5"
   757  // 	   NewFromFloat(545).Round(-1).String() // output: "550"
   758  //
   759  func (d Decimal) Round(places int32) Decimal {
   760  	// truncate to places + 1
   761  	ret := d.rescale(-places - 1)
   762  
   763  	// add sign(d) * 0.5
   764  	if ret.value.Sign() < 0 {
   765  		ret.value.Sub(ret.value, fiveInt)
   766  	} else {
   767  		ret.value.Add(ret.value, fiveInt)
   768  	}
   769  
   770  	// floor for positive numbers, ceil for negative numbers
   771  	_, m := ret.value.DivMod(ret.value, tenInt, new(big.Int))
   772  	ret.exp++
   773  	if ret.value.Sign() < 0 && m.Cmp(zeroInt) != 0 {
   774  		ret.value.Add(ret.value, oneInt)
   775  	}
   776  
   777  	return ret
   778  }
   779  
   780  // RoundBank rounds the decimal to places decimal places.
   781  // If the final digit to round is equidistant from the nearest two integers the
   782  // rounded value is taken as the even number
   783  //
   784  // If places < 0, it will round the integer part to the nearest 10^(-places).
   785  //
   786  // Examples:
   787  //
   788  // 	   NewFromFloat(5.45).Round(1).String() // output: "5.4"
   789  // 	   NewFromFloat(545).Round(-1).String() // output: "540"
   790  // 	   NewFromFloat(5.46).Round(1).String() // output: "5.5"
   791  // 	   NewFromFloat(546).Round(-1).String() // output: "550"
   792  // 	   NewFromFloat(5.55).Round(1).String() // output: "5.6"
   793  // 	   NewFromFloat(555).Round(-1).String() // output: "560"
   794  //
   795  func (d Decimal) RoundBank(places int32) Decimal {
   796  
   797  	round := d.Round(places)
   798  	remainder := d.Sub(round).Abs()
   799  
   800  	half := New(5, -places-1)
   801  	if remainder.Cmp(half) == 0 && round.value.Bit(0) != 0 {
   802  		if round.value.Sign() < 0 {
   803  			round.value.Add(round.value, oneInt)
   804  		} else {
   805  			round.value.Sub(round.value, oneInt)
   806  		}
   807  	}
   808  
   809  	return round
   810  }
   811  
   812  // RoundCash aka Cash/Penny/öre rounding rounds decimal to a specific
   813  // interval. The amount payable for a cash transaction is rounded to the nearest
   814  // multiple of the minimum currency unit available. The following intervals are
   815  // available: 5, 10, 15, 25, 50 and 100; any other number throws a panic.
   816  //	    5:   5 cent rounding 3.43 => 3.45
   817  // 	   10:  10 cent rounding 3.45 => 3.50 (5 gets rounded up)
   818  // 	   15:  10 cent rounding 3.45 => 3.40 (5 gets rounded down)
   819  // 	   25:  25 cent rounding 3.41 => 3.50
   820  // 	   50:  50 cent rounding 3.75 => 4.00
   821  // 	  100: 100 cent rounding 3.50 => 4.00
   822  // For more details: https://en.wikipedia.org/wiki/Cash_rounding
   823  func (d Decimal) RoundCash(interval uint8) Decimal {
   824  	var iVal *big.Int
   825  	switch interval {
   826  	case 5:
   827  		iVal = twentyInt
   828  	case 10:
   829  		iVal = tenInt
   830  	case 15:
   831  		if d.exp < 0 {
   832  			// TODO: optimize and reduce allocations
   833  			orgExp := d.exp
   834  			dOne := New(10^-int64(orgExp), orgExp)
   835  			d2 := d
   836  			d2.exp = 0
   837  			if d2.Mod(fiveDec).Equal(Zero) {
   838  				d2.exp = orgExp
   839  				d2 = d2.Sub(dOne)
   840  				d = d2
   841  			}
   842  		}
   843  		iVal = tenInt
   844  	case 25:
   845  		iVal = fourInt
   846  	case 50:
   847  		iVal = twoInt
   848  	case 100:
   849  		iVal = oneInt
   850  	default:
   851  		panic(fmt.Sprintf("Decimal does not support this Cash rounding interval `%d`. Supported: 5, 10, 15, 25, 50, 100", interval))
   852  	}
   853  	dVal := Decimal{
   854  		value: iVal,
   855  	}
   856  	// TODO: optimize those calculations to reduce the high allocations (~29 allocs).
   857  	return d.Mul(dVal).Round(0).Div(dVal).Truncate(2)
   858  }
   859  
   860  // Floor returns the nearest integer value less than or equal to d.
   861  func (d Decimal) Floor() Decimal {
   862  	d.ensureInitialized()
   863  
   864  	if d.exp >= 0 {
   865  		return d
   866  	}
   867  
   868  	exp := big.NewInt(10)
   869  
   870  	// NOTE(vadim): must negate after casting to prevent int32 overflow
   871  	exp.Exp(exp, big.NewInt(-int64(d.exp)), nil)
   872  
   873  	z := new(big.Int).Div(d.value, exp)
   874  	return Decimal{value: z, exp: 0}
   875  }
   876  
   877  // Ceil returns the nearest integer value greater than or equal to d.
   878  func (d Decimal) Ceil() Decimal {
   879  	d.ensureInitialized()
   880  
   881  	if d.exp >= 0 {
   882  		return d
   883  	}
   884  
   885  	exp := big.NewInt(10)
   886  
   887  	// NOTE(vadim): must negate after casting to prevent int32 overflow
   888  	exp.Exp(exp, big.NewInt(-int64(d.exp)), nil)
   889  
   890  	z, m := new(big.Int).DivMod(d.value, exp, new(big.Int))
   891  	if m.Cmp(zeroInt) != 0 {
   892  		z.Add(z, oneInt)
   893  	}
   894  	return Decimal{value: z, exp: 0}
   895  }
   896  
   897  // Truncate truncates off digits from the number, without rounding.
   898  //
   899  // NOTE: precision is the last digit that will not be truncated (must be >= 0).
   900  //
   901  // Example:
   902  //
   903  //     decimal.NewFromString("123.456").Truncate(2).String() // "123.45"
   904  //
   905  func (d Decimal) Truncate(precision int32) Decimal {
   906  	d.ensureInitialized()
   907  	if precision >= 0 && -precision > d.exp {
   908  		return d.rescale(-precision)
   909  	}
   910  	return d
   911  }
   912  
   913  // UnmarshalJSON implements the json.Unmarshaler interface.
   914  func (d *Decimal) UnmarshalJSON(decimalBytes []byte) error {
   915  	if string(decimalBytes) == "null" {
   916  		return nil
   917  	}
   918  
   919  	str, err := unquoteIfQuoted(decimalBytes)
   920  	if err != nil {
   921  		return fmt.Errorf("Error decoding string '%s': %s", decimalBytes, err)
   922  	}
   923  
   924  	decimal, err := NewFromString(str)
   925  	*d = decimal
   926  	if err != nil {
   927  		return fmt.Errorf("Error decoding string '%s': %s", str, err)
   928  	}
   929  	return nil
   930  }
   931  
   932  // MarshalJSON implements the json.Marshaler interface.
   933  func (d Decimal) MarshalJSON() ([]byte, error) {
   934  	var str string
   935  	if MarshalJSONWithoutQuotes {
   936  		str = d.String()
   937  	} else {
   938  		str = "\"" + d.String() + "\""
   939  	}
   940  	return []byte(str), nil
   941  }
   942  
   943  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. As a string representation
   944  // is already used when encoding to text, this method stores that string as []byte
   945  func (d *Decimal) UnmarshalBinary(data []byte) error {
   946  	// Extract the exponent
   947  	d.exp = int32(binary.BigEndian.Uint32(data[:4]))
   948  
   949  	// Extract the value
   950  	d.value = new(big.Int)
   951  	return d.value.GobDecode(data[4:])
   952  }
   953  
   954  // MarshalBinary implements the encoding.BinaryMarshaler interface.
   955  func (d Decimal) MarshalBinary() (data []byte, err error) {
   956  	// Write the exponent first since it's a fixed size
   957  	v1 := make([]byte, 4)
   958  	binary.BigEndian.PutUint32(v1, uint32(d.exp))
   959  
   960  	// Add the value
   961  	var v2 []byte
   962  	if v2, err = d.value.GobEncode(); err != nil {
   963  		return
   964  	}
   965  
   966  	// Return the byte array
   967  	data = append(v1, v2...)
   968  	return
   969  }
   970  
   971  // Scan implements the sql.Scanner interface for database deserialization.
   972  func (d *Decimal) Scan(value interface{}) error {
   973  	// first try to see if the data is stored in database as a Numeric datatype
   974  	switch v := value.(type) {
   975  
   976  	case float32:
   977  		*d = NewFromFloat(float64(v))
   978  		return nil
   979  
   980  	case float64:
   981  		// numeric in sqlite3 sends us float64
   982  		*d = NewFromFloat(v)
   983  		return nil
   984  
   985  	case int64:
   986  		// at least in sqlite3 when the value is 0 in db, the data is sent
   987  		// to us as an int64 instead of a float64 ...
   988  		*d = New(v, 0)
   989  		return nil
   990  
   991  	default:
   992  		// default is trying to interpret value stored as string
   993  		str, err := unquoteIfQuoted(v)
   994  		if err != nil {
   995  			return err
   996  		}
   997  		*d, err = NewFromString(str)
   998  		return err
   999  	}
  1000  }
  1001  
  1002  // Value implements the driver.Valuer interface for database serialization.
  1003  func (d Decimal) Value() (driver.Value, error) {
  1004  	return d.String(), nil
  1005  }
  1006  
  1007  // UnmarshalText implements the encoding.TextUnmarshaler interface for XML
  1008  // deserialization.
  1009  func (d *Decimal) UnmarshalText(text []byte) error {
  1010  	str := string(text)
  1011  
  1012  	dec, err := NewFromString(str)
  1013  	*d = dec
  1014  	if err != nil {
  1015  		return fmt.Errorf("Error decoding string '%s': %s", str, err)
  1016  	}
  1017  
  1018  	return nil
  1019  }
  1020  
  1021  // MarshalText implements the encoding.TextMarshaler interface for XML
  1022  // serialization.
  1023  func (d Decimal) MarshalText() (text []byte, err error) {
  1024  	return []byte(d.String()), nil
  1025  }
  1026  
  1027  // GobEncode implements the gob.GobEncoder interface for gob serialization.
  1028  func (d Decimal) GobEncode() ([]byte, error) {
  1029  	return d.MarshalBinary()
  1030  }
  1031  
  1032  // GobDecode implements the gob.GobDecoder interface for gob serialization.
  1033  func (d *Decimal) GobDecode(data []byte) error {
  1034  	return d.UnmarshalBinary(data)
  1035  }
  1036  
  1037  // StringScaled first scales the decimal then calls .String() on it.
  1038  // NOTE: buggy, unintuitive, and DEPRECATED! Use StringFixed instead.
  1039  func (d Decimal) StringScaled(exp int32) string {
  1040  	return d.rescale(exp).String()
  1041  }
  1042  
  1043  func (d Decimal) string(trimTrailingZeros bool) string {
  1044  	if d.exp >= 0 {
  1045  		return d.rescale(0).value.String()
  1046  	}
  1047  
  1048  	abs := new(big.Int).Abs(d.value)
  1049  	str := abs.String()
  1050  
  1051  	var intPart, fractionalPart string
  1052  
  1053  	// NOTE(vadim): this cast to int will cause bugs if d.exp == INT_MIN
  1054  	// and you are on a 32-bit machine. Won't fix this super-edge case.
  1055  	dExpInt := int(d.exp)
  1056  	if len(str) > -dExpInt {
  1057  		intPart = str[:len(str)+dExpInt]
  1058  		fractionalPart = str[len(str)+dExpInt:]
  1059  	} else {
  1060  		intPart = "0"
  1061  
  1062  		num0s := -dExpInt - len(str)
  1063  		fractionalPart = strings.Repeat("0", num0s) + str
  1064  	}
  1065  
  1066  	if trimTrailingZeros {
  1067  		i := len(fractionalPart) - 1
  1068  		for ; i >= 0; i-- {
  1069  			if fractionalPart[i] != '0' {
  1070  				break
  1071  			}
  1072  		}
  1073  		fractionalPart = fractionalPart[:i+1]
  1074  	}
  1075  
  1076  	number := intPart
  1077  	if len(fractionalPart) > 0 {
  1078  		number += "." + fractionalPart
  1079  	}
  1080  
  1081  	if d.value.Sign() < 0 {
  1082  		return "-" + number
  1083  	}
  1084  
  1085  	return number
  1086  }
  1087  
  1088  func (d *Decimal) ensureInitialized() {
  1089  	if d.value == nil {
  1090  		d.value = new(big.Int)
  1091  	}
  1092  }
  1093  
  1094  // Min returns the smallest Decimal that was passed in the arguments.
  1095  //
  1096  // To call this function with an array, you must do:
  1097  //
  1098  //     Min(arr[0], arr[1:]...)
  1099  //
  1100  // This makes it harder to accidentally call Min with 0 arguments.
  1101  func Min(first Decimal, rest ...Decimal) Decimal {
  1102  	ans := first
  1103  	for _, item := range rest {
  1104  		if item.Cmp(ans) < 0 {
  1105  			ans = item
  1106  		}
  1107  	}
  1108  	return ans
  1109  }
  1110  
  1111  // Max returns the largest Decimal that was passed in the arguments.
  1112  //
  1113  // To call this function with an array, you must do:
  1114  //
  1115  //     Max(arr[0], arr[1:]...)
  1116  //
  1117  // This makes it harder to accidentally call Max with 0 arguments.
  1118  func Max(first Decimal, rest ...Decimal) Decimal {
  1119  	ans := first
  1120  	for _, item := range rest {
  1121  		if item.Cmp(ans) > 0 {
  1122  			ans = item
  1123  		}
  1124  	}
  1125  	return ans
  1126  }
  1127  
  1128  // Sum returns the combined total of the provided first and rest Decimals
  1129  func Sum(first Decimal, rest ...Decimal) Decimal {
  1130  	total := first
  1131  	for _, item := range rest {
  1132  		total = total.Add(item)
  1133  	}
  1134  
  1135  	return total
  1136  }
  1137  
  1138  // Avg returns the average value of the provided first and rest Decimals
  1139  func Avg(first Decimal, rest ...Decimal) Decimal {
  1140  	count := New(int64(len(rest)+1), 0)
  1141  	sum := Sum(first, rest...)
  1142  	return sum.Div(count)
  1143  }
  1144  
  1145  func min(x, y int32) int32 {
  1146  	if x >= y {
  1147  		return y
  1148  	}
  1149  	return x
  1150  }
  1151  
  1152  func unquoteIfQuoted(value interface{}) (string, error) {
  1153  	var bytes []byte
  1154  
  1155  	switch v := value.(type) {
  1156  	case string:
  1157  		bytes = []byte(v)
  1158  	case []byte:
  1159  		bytes = v
  1160  	default:
  1161  		return "", fmt.Errorf("Could not convert value '%+v' to byte array of type '%T'",
  1162  			value, value)
  1163  	}
  1164  
  1165  	// If the amount is quoted, strip the quotes
  1166  	if len(bytes) > 2 && bytes[0] == '"' && bytes[len(bytes)-1] == '"' {
  1167  		bytes = bytes[1 : len(bytes)-1]
  1168  	}
  1169  	return string(bytes), nil
  1170  }
  1171  
  1172  // NullDecimal represents a nullable decimal with compatibility for
  1173  // scanning null values from the database.
  1174  type NullDecimal struct {
  1175  	Decimal Decimal
  1176  	Valid   bool
  1177  }
  1178  
  1179  // Scan implements the sql.Scanner interface for database deserialization.
  1180  func (d *NullDecimal) Scan(value interface{}) error {
  1181  	if value == nil {
  1182  		d.Valid = false
  1183  		return nil
  1184  	}
  1185  	d.Valid = true
  1186  	return d.Decimal.Scan(value)
  1187  }
  1188  
  1189  // Value implements the driver.Valuer interface for database serialization.
  1190  func (d NullDecimal) Value() (driver.Value, error) {
  1191  	if !d.Valid {
  1192  		return nil, nil
  1193  	}
  1194  	return d.Decimal.Value()
  1195  }
  1196  
  1197  // UnmarshalJSON implements the json.Unmarshaler interface.
  1198  func (d *NullDecimal) UnmarshalJSON(decimalBytes []byte) error {
  1199  	if string(decimalBytes) == "null" {
  1200  		d.Valid = false
  1201  		return nil
  1202  	}
  1203  	d.Valid = true
  1204  	return d.Decimal.UnmarshalJSON(decimalBytes)
  1205  }
  1206  
  1207  // MarshalJSON implements the json.Marshaler interface.
  1208  func (d NullDecimal) MarshalJSON() ([]byte, error) {
  1209  	if !d.Valid {
  1210  		return []byte("null"), nil
  1211  	}
  1212  	return d.Decimal.MarshalJSON()
  1213  }
  1214  
  1215  // Trig functions
  1216  
  1217  // Atan returns the arctangent, in radians, of x.
  1218  func (x Decimal) Atan() Decimal {
  1219  	if x.Equal(NewFromFloat(0.0)) {
  1220  		return x
  1221  	}
  1222  	if x.GreaterThan(NewFromFloat(0.0)) {
  1223  		return x.satan()
  1224  	}
  1225  	return x.Neg().satan().Neg()
  1226  }
  1227  
  1228  func (d Decimal) xatan() Decimal {
  1229  	P0 := NewFromFloat(-8.750608600031904122785e-01)
  1230  	P1 := NewFromFloat(-1.615753718733365076637e+01)
  1231  	P2 := NewFromFloat(-7.500855792314704667340e+01)
  1232  	P3 := NewFromFloat(-1.228866684490136173410e+02)
  1233  	P4 := NewFromFloat(-6.485021904942025371773e+01)
  1234  	Q0 := NewFromFloat(2.485846490142306297962e+01)
  1235  	Q1 := NewFromFloat(1.650270098316988542046e+02)
  1236  	Q2 := NewFromFloat(4.328810604912902668951e+02)
  1237  	Q3 := NewFromFloat(4.853903996359136964868e+02)
  1238  	Q4 := NewFromFloat(1.945506571482613964425e+02)
  1239  	z := d.Mul(d)
  1240  	b1 := P0.Mul(z).Add(P1).Mul(z).Add(P2).Mul(z).Add(P3).Mul(z).Add(P4).Mul(z)
  1241  	b2 := z.Add(Q0).Mul(z).Add(Q1).Mul(z).Add(Q2).Mul(z).Add(Q3).Mul(z).Add(Q4)
  1242  	z = b1.Div(b2)
  1243  	z = d.Mul(z).Add(d)
  1244  	return z
  1245  }
  1246  
  1247  // satan reduces its argument (known to be positive)
  1248  // to the range [0, 0.66] and calls xatan.
  1249  func (d Decimal) satan() Decimal {
  1250  	Morebits := NewFromFloat(6.123233995736765886130e-17) // pi/2 = PIO2 + Morebits
  1251  	Tan3pio8 := NewFromFloat(2.41421356237309504880)      // tan(3*pi/8)
  1252  	pi := NewFromFloat(3.14159265358979323846264338327950288419716939937510582097494459)
  1253  
  1254  	if d.LessThanOrEqual(NewFromFloat(0.66)) {
  1255  		return d.xatan()
  1256  	}
  1257  	if d.GreaterThan(Tan3pio8) {
  1258  		return pi.Div(NewFromFloat(2.0)).Sub(NewFromFloat(1.0).Div(d).xatan()).Add(Morebits)
  1259  	}
  1260  	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))
  1261  }
  1262  
  1263  // sin coefficients
  1264    var _sin = [...]Decimal{
  1265    	NewFromFloat(1.58962301576546568060E-10), // 0x3de5d8fd1fd19ccd
  1266    	NewFromFloat(-2.50507477628578072866E-8), // 0xbe5ae5e5a9291f5d
  1267    	NewFromFloat(2.75573136213857245213E-6),  // 0x3ec71de3567d48a1
  1268    	NewFromFloat(-1.98412698295895385996E-4), // 0xbf2a01a019bfdf03
  1269    	NewFromFloat(8.33333333332211858878E-3),  // 0x3f8111111110f7d0
  1270    	NewFromFloat(-1.66666666666666307295E-1), // 0xbfc5555555555548
  1271    }
  1272  
  1273  // Sin returns the sine of the radian argument x.
  1274    func (d Decimal) Sin() Decimal {
  1275  		PI4A := NewFromFloat(7.85398125648498535156E-1)                             // 0x3fe921fb40000000, Pi/4 split into three parts
  1276  		PI4B := NewFromFloat(3.77489470793079817668E-8)                             // 0x3e64442d00000000,
  1277  		PI4C := NewFromFloat(2.69515142907905952645E-15)                            // 0x3ce8469898cc5170,
  1278  		M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
  1279  
  1280    	if d.Equal(NewFromFloat(0.0)) {
  1281  			return d
  1282  		}
  1283    	// make argument positive but save the sign
  1284    	sign := false
  1285    	if d.LessThan(NewFromFloat(0.0)) {
  1286    		d = d.Neg()
  1287    		sign = true
  1288    	}
  1289  
  1290  		j := d.Mul(M4PI).IntPart()    // integer part of x/(Pi/4), as integer for tests on the phase angle
  1291    	y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
  1292  
  1293    	// map zeros to origin
  1294    	if j&1 == 1 {
  1295    		j++
  1296    		y = y.Add(NewFromFloat(1.0))
  1297    	}
  1298    	j &= 7 // octant modulo 2Pi radians (360 degrees)
  1299    	// reflect in x axis
  1300    	if j > 3 {
  1301    		sign = !sign
  1302    		j -= 4
  1303    	}
  1304  		z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
  1305    	zz := z.Mul(z)
  1306  
  1307    	if j == 1 || j == 2 {
  1308  			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]))
  1309  			y = NewFromFloat(1.0).Sub(NewFromFloat(0.5).Mul(zz)).Add(w)
  1310    	} else {
  1311  			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])))
  1312    	}
  1313    	if sign {
  1314    		y = y.Neg()
  1315    	}
  1316    	return y
  1317    }
  1318  
  1319  	// cos coefficients
  1320    var _cos = [...]Decimal{
  1321    	NewFromFloat(-1.13585365213876817300E-11), // 0xbda8fa49a0861a9b
  1322    	NewFromFloat(2.08757008419747316778E-9),   // 0x3e21ee9d7b4e3f05
  1323    	NewFromFloat(-2.75573141792967388112E-7),  // 0xbe927e4f7eac4bc6
  1324    	NewFromFloat(2.48015872888517045348E-5),   // 0x3efa01a019c844f5
  1325    	NewFromFloat(-1.38888888888730564116E-3),  // 0xbf56c16c16c14f91
  1326    	NewFromFloat(4.16666666666665929218E-2),   // 0x3fa555555555554b
  1327    }
  1328  
  1329  	// Cos returns the cosine of the radian argument x.
  1330    func (d Decimal) Cos() Decimal {
  1331  
  1332  		PI4A := NewFromFloat(7.85398125648498535156E-1)                             // 0x3fe921fb40000000, Pi/4 split into three parts
  1333  		PI4B := NewFromFloat(3.77489470793079817668E-8)                             // 0x3e64442d00000000,
  1334  		PI4C := NewFromFloat(2.69515142907905952645E-15)                            // 0x3ce8469898cc5170,
  1335  		M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
  1336  
  1337    	// make argument positive
  1338  		sign := false
  1339    	if d.LessThan(NewFromFloat(0.0)) {
  1340    		d = d.Neg()
  1341    	}
  1342  
  1343  		j := d.Mul(M4PI).IntPart()    // integer part of x/(Pi/4), as integer for tests on the phase angle
  1344    	y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
  1345  
  1346    	// map zeros to origin
  1347    	if j&1 == 1 {
  1348    		j++
  1349    		y = y.Add(NewFromFloat(1.0))
  1350    	}
  1351    	j &= 7 // octant modulo 2Pi radians (360 degrees)
  1352    	// reflect in x axis
  1353    	if j > 3 {
  1354    		sign = !sign
  1355    		j -= 4
  1356    	}
  1357  		if j > 1 {
  1358    		sign = !sign
  1359    	}
  1360  
  1361  		z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
  1362    	zz := z.Mul(z)
  1363  
  1364    	if j == 1 || j == 2 {
  1365  			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])))
  1366    	} else {
  1367  			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]))
  1368  			y = NewFromFloat(1.0).Sub(NewFromFloat(0.5).Mul(zz)).Add(w)
  1369    	}
  1370    	if sign {
  1371    		y = y.Neg()
  1372    	}
  1373    	return y
  1374    }
  1375  
  1376  	var _tanP = [...]Decimal{
  1377    	NewFromFloat(-1.30936939181383777646E+4), // 0xc0c992d8d24f3f38
  1378    	NewFromFloat(1.15351664838587416140E+6),  // 0x413199eca5fc9ddd
  1379    	NewFromFloat(-1.79565251976484877988E+7), // 0xc1711fead3299176
  1380    }
  1381    var _tanQ = [...]Decimal{
  1382    	NewFromFloat(1.00000000000000000000E+0),
  1383    	NewFromFloat(1.36812963470692954678E+4),  //0x40cab8a5eeb36572
  1384    	NewFromFloat(-1.32089234440210967447E+6), //0xc13427bc582abc96
  1385    	NewFromFloat(2.50083801823357915839E+7),  //0x4177d98fc2ead8ef
  1386    	NewFromFloat(-5.38695755929454629881E+7), //0xc189afe03cbe5a31
  1387    }
  1388  
  1389    // Tan returns the tangent of the radian argument x.
  1390    func (d Decimal) Tan() Decimal {
  1391  
  1392  		PI4A := NewFromFloat(7.85398125648498535156E-1)                             // 0x3fe921fb40000000, Pi/4 split into three parts
  1393  		PI4B := NewFromFloat(3.77489470793079817668E-8)                             // 0x3e64442d00000000,
  1394  		PI4C := NewFromFloat(2.69515142907905952645E-15)                            // 0x3ce8469898cc5170,
  1395  		M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
  1396  
  1397  		if d.Equal(NewFromFloat(0.0)) {
  1398  			return d
  1399  		}
  1400  
  1401    	// make argument positive but save the sign
  1402    	sign := false
  1403    	if d.LessThan(NewFromFloat(0.0)) {
  1404    		d = d.Neg()
  1405    		sign = true
  1406    	}
  1407  
  1408  		j := d.Mul(M4PI).IntPart()    // integer part of x/(Pi/4), as integer for tests on the phase angle
  1409    	y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
  1410  
  1411    	// map zeros to origin
  1412    	if j&1 == 1 {
  1413    		j++
  1414    		y = y.Add(NewFromFloat(1.0))
  1415    	}
  1416  
  1417  		z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
  1418    	zz := z.Mul(z)
  1419  
  1420    	if zz.GreaterThan(NewFromFloat(1e-14)) {
  1421  			w := zz.Mul(_tanP[0].Mul(zz).Add(_tanP[1]).Mul(zz).Add(_tanP[2]))
  1422  			x := zz.Add(_tanQ[1]).Mul(zz).Add(_tanQ[2]).Mul(zz).Add(_tanQ[3]).Mul(zz).Add(_tanQ[4])
  1423  			y = z.Add(z.Mul(w.Div(x)))
  1424    	} else {
  1425    		y = z
  1426    	}
  1427    	if j&2 == 2 {
  1428  			y = NewFromFloat(-1.0).Div(y)
  1429    	}
  1430    	if sign {
  1431    		y = y.Neg()
  1432    	}
  1433    	return y
  1434    }