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