1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44 var DivisionPrecision = 16
45
46
47
48
49
50
51
52
53
54
55
56
57
58 var PowPrecisionNegativeExponent = 16
59
60
61
62
63
64
65
66 var MarshalJSONWithoutQuotes = false
67
68
69
70 var ExpMaxIterations = 1000
71
72
73
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
87
88 type Decimal struct {
89 value *big.Int
90
91
92
93
94
95
96 exp int32
97 }
98
99
100 func New(value int64, exp int32) Decimal {
101 return Decimal{
102 value: big.NewInt(value),
103 exp: exp,
104 }
105 }
106
107
108
109
110
111
112
113 func NewFromInt(value int64) Decimal {
114 return Decimal{
115 value: big.NewInt(value),
116 exp: 0,
117 }
118 }
119
120
121
122
123
124
125
126 func NewFromInt32(value int32) Decimal {
127 return Decimal{
128 value: big.NewInt(int64(value)),
129 exp: 0,
130 }
131 }
132
133
134
135
136
137
138 func NewFromUint64(value uint64) Decimal {
139 return Decimal{
140 value: new(big.Int).SetUint64(value),
141 exp: 0,
142 }
143 }
144
145
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
154
155
156
157
158
159
160
161
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
173
174
175
176
177
178
179
180 func NewFromString(value string) (Decimal, error) {
181 originalInput := value
182 var intString string
183 var exp int64
184
185
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
212
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
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
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
252
253
254
255
256
257
258
259
260
261
262
263
264
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
275
276
277
278
279
280
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
290
291
292
293
294
295
296
297
298
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
307
308
309
310
311
312
313
314
315
316 func NewFromFloat32(value float32) Decimal {
317 if value == 0 {
318 return New(0, 0)
319 }
320
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
335 exp++
336
337 default:
338
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
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
372
373
374
375
376
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
389 if mant == 0 {
390 return Decimal{}
391 }
392
393 exp2++
394 } else {
395
396 mant |= 1 << 52
397 }
398
399 exp2 -= 1023 + 52
400
401
402 for mant&1 == 0 {
403 mant = mant >> 1
404 exp2++
405 }
406
407
408 if exp < 0 && exp < exp2 {
409 if exp2 < 0 {
410 exp = exp2
411 } else {
412 exp = 0
413 }
414 }
415
416
417 exp2 -= exp
418
419 temp := big.NewInt(1)
420 dMant := big.NewInt(int64(mant))
421
422
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
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
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
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
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
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
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
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
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
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
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
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
565
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
577
578
579
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
589
590 func (d Decimal) Div(d2 Decimal) Decimal {
591 return d.DivRound(d2, int32(DivisionPrecision))
592 }
593
594
595
596
597
598
599
600
601
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
616
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
624
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
632
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
642
643
644
645
646
647
648 func (d Decimal) DivRound(d2 Decimal, precision int32) Decimal {
649
650 q, r := d.QuoRem(d2, precision)
651
652
653 var rv2 big.Int
654 rv2.Abs(r.value)
655 rv2.Lsh(&rv2, 1)
656
657 r2 := Decimal{value: &rv2, exp: r.exp + precision}
658
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
673 func (d Decimal) Mod(d2 Decimal) Decimal {
674 _, r := d.QuoRem(d2, 0)
675 return r
676 }
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
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
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
729 if expFracPart.value.Sign() == 0 {
730 return intPartPow
731 }
732
733
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
746
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
760
761 res := intPartPow.Mul(fracPartPow)
762
763 return res
764 }
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
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
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
822 if expFracPart.value.Sign() == 0 {
823 return intPartPow, nil
824 }
825
826
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
837 precision += 10
838
839
840
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
854
855 res := intPartPow.Mul(fracPartPow)
856
857 return res, nil
858 }
859
860
861
862
863
864
865
866
867
868
869
870
871
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
901
902
903
904
905
906
907
908
909
910
911
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
949
950
951
952
953
954
955
956
957 func (d Decimal) ExpHullAbrham(overallPrecision uint32) (Decimal, error) {
958
959
960 if d.IsZero() {
961 return Decimal{oneInt, 0}, nil
962 }
963
964 currentPrecision := overallPrecision
965
966
967
968
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
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
981 overflowThreshold2 := New(9, -int32(currentPrecision)-1)
982 if d.Abs().Cmp(overflowThreshold2) <= 0 {
983 return Decimal{oneInt, d.exp}, nil
984 }
985
986
987 t := d.exp + int32(d.NumDigits())
988
989 if t < 0 {
990 t = 0
991 }
992
993 k := New(1, t)
994 r := Decimal{new(big.Int).Set(d.value), d.exp - t}
995 p := int32(currentPrecision) + t + 2
996
997
998
999
1000
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
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054 func (d Decimal) ExpTaylor(precision int32) (Decimal, error) {
1055
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
1081 if step.Cmp(epsilon) < 0 {
1082 break
1083 }
1084
1085 pow = pow.Mul(decAbs)
1086
1087 i++
1088
1089
1090 if len(factorials) >= int(i) && !factorials[i-1].IsZero() {
1091 factorial = factorials[i-1]
1092 } else {
1093
1094
1095
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
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121 func (d Decimal) Ln(precision int32) (Decimal, error) {
1122
1123
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
1140 usePowerSeries := false
1141
1142 if comp1.Abs().Cmp(comp3) <= 0 {
1143 usePowerSeries = true
1144 } else {
1145
1146 expDelta := int32(z.NumDigits()) + z.exp
1147 z.exp -= expDelta
1148
1149
1150
1151
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
1162 zFloat := z.InexactFloat64()
1163 comp1 = NewFromFloat(math.Log(zFloat))
1164 }
1165 }
1166
1167 epsilon := Decimal{oneInt, -calcPrecision}
1168
1169 if usePowerSeries {
1170
1171
1172
1173
1174
1175
1176 comp2 = comp1.Add(Decimal{twoInt, 0})
1177
1178 comp3 = comp1.DivRound(comp2, calcPrecision)
1179
1180 comp1 = comp3.Add(comp3)
1181 comp2 = comp1.Copy()
1182
1183 for n := 1; ; n++ {
1184
1185 comp2 = comp2.Mul(comp3).Mul(comp3)
1186
1187
1188 comp4 = NewFromInt(int64(2*n + 1))
1189 comp4 = comp2.DivRound(comp4, calcPrecision)
1190
1191
1192 comp1 = comp1.Add(comp4)
1193
1194 if comp4.Abs().Cmp(epsilon) <= 0 {
1195 break
1196 }
1197 }
1198 } else {
1199
1200
1201
1202 var prevStep Decimal
1203 maxIters := calcPrecision*2 + 10
1204
1205 for i := int32(0); i < maxIters; i++ {
1206
1207 comp3, _ = comp1.ExpTaylor(calcPrecision)
1208
1209 comp2 = comp3.Sub(z)
1210
1211 comp2 = comp2.Add(comp2)
1212
1213 comp4 = comp3.Add(z)
1214
1215 comp3 = comp2.DivRound(comp4, calcPrecision)
1216
1217 comp1 = comp1.Sub(comp3)
1218
1219 if prevStep.Add(comp3).IsZero() {
1220
1221
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
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
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
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
1269 func (d Decimal) IsInteger() bool {
1270
1271 if d.exp >= 0 {
1272 return true
1273 }
1274
1275
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
1288 func abs(n int32) int32 {
1289 if n < 0 {
1290 return -n
1291 }
1292 return n
1293 }
1294
1295
1296
1297
1298
1299
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
1314
1315
1316
1317
1318 func (d Decimal) Compare(d2 Decimal) int {
1319 return d.Cmp(d2)
1320 }
1321
1322
1323 func (d Decimal) Equal(d2 Decimal) bool {
1324 return d.Cmp(d2) == 0
1325 }
1326
1327
1328 func (d Decimal) Equals(d2 Decimal) bool {
1329 return d.Equal(d2)
1330 }
1331
1332
1333 func (d Decimal) GreaterThan(d2 Decimal) bool {
1334 return d.Cmp(d2) == 1
1335 }
1336
1337
1338 func (d Decimal) GreaterThanOrEqual(d2 Decimal) bool {
1339 cmp := d.Cmp(d2)
1340 return cmp == 1 || cmp == 0
1341 }
1342
1343
1344 func (d Decimal) LessThan(d2 Decimal) bool {
1345 return d.Cmp(d2) == -1
1346 }
1347
1348
1349 func (d Decimal) LessThanOrEqual(d2 Decimal) bool {
1350 cmp := d.Cmp(d2)
1351 return cmp == -1 || cmp == 0
1352 }
1353
1354
1355
1356
1357
1358
1359 func (d Decimal) Sign() int {
1360 if d.value == nil {
1361 return 0
1362 }
1363 return d.value.Sign()
1364 }
1365
1366
1367
1368
1369
1370
1371 func (d Decimal) IsPositive() bool {
1372 return d.Sign() == 1
1373 }
1374
1375
1376
1377
1378
1379
1380 func (d Decimal) IsNegative() bool {
1381 return d.Sign() == -1
1382 }
1383
1384
1385
1386
1387
1388
1389 func (d Decimal) IsZero() bool {
1390 return d.Sign() == 0
1391 }
1392
1393
1394 func (d Decimal) Exponent() int32 {
1395 return d.exp
1396 }
1397
1398
1399 func (d Decimal) Coefficient() *big.Int {
1400 d.ensureInitialized()
1401
1402 return new(big.Int).Set(d.value)
1403 }
1404
1405
1406
1407 func (d Decimal) CoefficientInt64() int64 {
1408 d.ensureInitialized()
1409 return d.value.Int64()
1410 }
1411
1412
1413 func (d Decimal) IntPart() int64 {
1414 scaledD := d.rescale(0)
1415 return scaledD.value.Int64()
1416 }
1417
1418
1419 func (d Decimal) BigInt() *big.Int {
1420 scaledD := d.rescale(0)
1421 return scaledD.value
1422 }
1423
1424
1425
1426 func (d Decimal) BigFloat() *big.Float {
1427 f := &big.Float{}
1428 f.SetString(d.String())
1429 return f
1430 }
1431
1432
1433 func (d Decimal) Rat() *big.Rat {
1434 d.ensureInitialized()
1435 if d.exp <= 0 {
1436
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
1447
1448
1449 func (d Decimal) Float64() (f float64, exact bool) {
1450 return d.Rat().Float64()
1451 }
1452
1453
1454
1455 func (d Decimal) InexactFloat64() float64 {
1456 f, _ := d.Float64()
1457 return f
1458 }
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471 func (d Decimal) String() string {
1472 return d.string(true)
1473 }
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487 func (d Decimal) StringFixed(places int32) string {
1488 rounded := d.Round(places)
1489 return rounded.string(false)
1490 }
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504 func (d Decimal) StringFixedBank(places int32) string {
1505 rounded := d.RoundBank(places)
1506 return rounded.string(false)
1507 }
1508
1509
1510
1511 func (d Decimal) StringFixedCash(interval uint8) string {
1512 rounded := d.RoundCash(interval)
1513 return rounded.string(false)
1514 }
1515
1516
1517
1518
1519
1520
1521
1522
1523 func (d Decimal) Round(places int32) Decimal {
1524 if d.exp == -places {
1525 return d
1526 }
1527
1528 ret := d.rescale(-places - 1)
1529
1530
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
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
1548
1549
1550
1551
1552
1553
1554
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
1573
1574
1575
1576
1577
1578
1579
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
1598
1599
1600
1601
1602
1603
1604
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
1625
1626
1627
1628
1629
1630
1631
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
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
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
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
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
1708 return d.Mul(dVal).Round(0).Div(dVal).Truncate(2)
1709 }
1710
1711
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
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
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
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
1749
1750
1751
1752
1753
1754
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
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
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
1794
1795 func (d *Decimal) UnmarshalBinary(data []byte) error {
1796
1797
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
1803 d.exp = int32(binary.BigEndian.Uint32(data[:4]))
1804
1805
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
1815 func (d Decimal) MarshalBinary() (data []byte, err error) {
1816
1817 var valueData []byte
1818 if valueData, err = d.value.GobEncode(); err != nil {
1819 return nil, err
1820 }
1821
1822
1823 expData := make([]byte, 4, len(valueData)+4)
1824 binary.BigEndian.PutUint32(expData, uint32(d.exp))
1825
1826
1827 return append(expData, valueData...), nil
1828 }
1829
1830
1831 func (d *Decimal) Scan(value interface{}) error {
1832
1833 switch v := value.(type) {
1834
1835 case float32:
1836 *d = NewFromFloat(float64(v))
1837 return nil
1838
1839 case float64:
1840
1841 *d = NewFromFloat(v)
1842 return nil
1843
1844 case int64:
1845
1846
1847 *d = New(v, 0)
1848 return nil
1849
1850 case uint64:
1851
1852 *d = NewFromUint64(v)
1853 return nil
1854
1855 default:
1856
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
1867 func (d Decimal) Value() (driver.Value, error) {
1868 return d.String(), nil
1869 }
1870
1871
1872
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
1886
1887 func (d Decimal) MarshalText() (text []byte, err error) {
1888 return []byte(d.String()), nil
1889 }
1890
1891
1892 func (d Decimal) GobEncode() ([]byte, error) {
1893 return d.MarshalBinary()
1894 }
1895
1896
1897 func (d *Decimal) GobDecode(data []byte) error {
1898 return d.UnmarshalBinary(data)
1899 }
1900
1901
1902
1903
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
1919
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
1960
1961
1962
1963
1964
1965
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
1977
1978
1979
1980
1981
1982
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
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
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
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
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
2044
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
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
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
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
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
2094
2095 func (d *NullDecimal) UnmarshalText(text []byte) error {
2096 str := string(text)
2097
2098
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
2112
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
2121
2122
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
2153
2154 func (d Decimal) satan() Decimal {
2155 Morebits := NewFromFloat(6.123233995736765886130e-17)
2156 Tan3pio8 := NewFromFloat(2.41421356237309504880)
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
2169 var _sin = [...]Decimal{
2170 NewFromFloat(1.58962301576546568060e-10),
2171 NewFromFloat(-2.50507477628578072866e-8),
2172 NewFromFloat(2.75573136213857245213e-6),
2173 NewFromFloat(-1.98412698295895385996e-4),
2174 NewFromFloat(8.33333333332211858878e-3),
2175 NewFromFloat(-1.66666666666666307295e-1),
2176 }
2177
2178
2179 func (d Decimal) Sin() Decimal {
2180 PI4A := NewFromFloat(7.85398125648498535156e-1)
2181 PI4B := NewFromFloat(3.77489470793079817668e-8)
2182 PI4C := NewFromFloat(2.69515142907905952645e-15)
2183 M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125)
2184
2185 if d.Equal(NewFromFloat(0.0)) {
2186 return d
2187 }
2188
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()
2196 y := NewFromFloat(float64(j))
2197
2198
2199 if j&1 == 1 {
2200 j++
2201 y = y.Add(NewFromFloat(1.0))
2202 }
2203 j &= 7
2204
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))
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
2225 var _cos = [...]Decimal{
2226 NewFromFloat(-1.13585365213876817300e-11),
2227 NewFromFloat(2.08757008419747316778e-9),
2228 NewFromFloat(-2.75573141792967388112e-7),
2229 NewFromFloat(2.48015872888517045348e-5),
2230 NewFromFloat(-1.38888888888730564116e-3),
2231 NewFromFloat(4.16666666666665929218e-2),
2232 }
2233
2234
2235 func (d Decimal) Cos() Decimal {
2236
2237 PI4A := NewFromFloat(7.85398125648498535156e-1)
2238 PI4B := NewFromFloat(3.77489470793079817668e-8)
2239 PI4C := NewFromFloat(2.69515142907905952645e-15)
2240 M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125)
2241
2242
2243 sign := false
2244 if d.LessThan(NewFromFloat(0.0)) {
2245 d = d.Neg()
2246 }
2247
2248 j := d.Mul(M4PI).IntPart()
2249 y := NewFromFloat(float64(j))
2250
2251
2252 if j&1 == 1 {
2253 j++
2254 y = y.Add(NewFromFloat(1.0))
2255 }
2256 j &= 7
2257
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))
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),
2283 NewFromFloat(1.15351664838587416140e+6),
2284 NewFromFloat(-1.79565251976484877988e+7),
2285 }
2286 var _tanQ = [...]Decimal{
2287 NewFromFloat(1.00000000000000000000e+0),
2288 NewFromFloat(1.36812963470692954678e+4),
2289 NewFromFloat(-1.32089234440210967447e+6),
2290 NewFromFloat(2.50083801823357915839e+7),
2291 NewFromFloat(-5.38695755929454629881e+7),
2292 }
2293
2294
2295 func (d Decimal) Tan() Decimal {
2296
2297 PI4A := NewFromFloat(7.85398125648498535156e-1)
2298 PI4B := NewFromFloat(3.77489470793079817668e-8)
2299 PI4C := NewFromFloat(2.69515142907905952645e-15)
2300 M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125)
2301
2302 if d.Equal(NewFromFloat(0.0)) {
2303 return d
2304 }
2305
2306
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()
2314 y := NewFromFloat(float64(j))
2315
2316
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))
2323 zz := z.Mul(z)
2324
2325 if zz.GreaterThan(NewFromFloat(1e-14)) {
2326 w := zz.Mul(_tanP[0].Mul(zz).Add(_tanP[1]).Mul(zz).Add(_tanP[2]))
2327 x := zz.Add(_tanQ[1]).Mul(zz).Add(_tanQ[2]).Mul(zz).Add(_tanQ[3]).Mul(zz).Add(_tanQ[4])
2328 y = z.Add(z.Mul(w.Div(x)))
2329 } else {
2330 y = z
2331 }
2332 if j&2 == 2 {
2333 y = NewFromFloat(-1.0).Div(y)
2334 }
2335 if sign {
2336 y = y.Neg()
2337 }
2338 return y
2339 }
2340
View as plain text