1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package apd
16
17 import (
18 "encoding/json"
19 "fmt"
20 "math"
21 "math/bits"
22 "strings"
23 "testing"
24 "unsafe"
25 )
26
27 var (
28 testCtx = &BaseContext
29 )
30
31 func (d *Decimal) GoString() string {
32 return fmt.Sprintf(`{Coeff: %s, Exponent: %d, Negative: %v, Form: %s}`, d.Coeff.String(), d.Exponent, d.Negative, d.Form)
33 }
34
35
36
37
38
39 func testExponentError(t *testing.T, err error) {
40 if err == nil {
41 return
42 }
43 if err.Error() == errExponentOutOfRangeStr {
44 t.Skip(err)
45 }
46 }
47
48 func newDecimal(t *testing.T, c *Context, s string) *Decimal {
49 d, _, err := c.NewFromString(s)
50 testExponentError(t, err)
51 if err != nil {
52 t.Fatalf("%s: %+v", s, err)
53 }
54 return d
55 }
56
57 func TestNewWithBigInt(t *testing.T) {
58 tests := []string{
59 "0",
60 "1",
61 "-1",
62 }
63 for _, tc := range tests {
64 t.Run(tc, func(t *testing.T) {
65 expect, _, err := new(Decimal).SetString(tc)
66 if err != nil {
67 t.Fatal(err)
68 }
69 b, ok := new(BigInt).SetString(tc, 10)
70 if !ok {
71 t.Fatal("bad bigint")
72 }
73 d := NewWithBigInt(b, 0)
74 if d.Coeff.Sign() < 0 {
75 t.Fatal("unexpected negative coeff")
76 }
77
78 b.Set(NewBigInt(1234))
79 if d.CmpTotal(expect) != 0 {
80 t.Fatalf("expected %s, got %s", expect, d)
81 }
82 })
83 }
84 }
85
86 func TestUpscale(t *testing.T) {
87 tests := []struct {
88 x, y *Decimal
89 a, b *BigInt
90 s int32
91 }{
92 {x: New(1, 0), y: New(100, -1), a: NewBigInt(10), b: NewBigInt(100), s: -1},
93 {x: New(1, 0), y: New(10, -1), a: NewBigInt(10), b: NewBigInt(10), s: -1},
94 {x: New(1, 0), y: New(10, 0), a: NewBigInt(1), b: NewBigInt(10), s: 0},
95 {x: New(1, 1), y: New(1, 0), a: NewBigInt(10), b: NewBigInt(1), s: 0},
96 {x: New(10, -2), y: New(1, -1), a: NewBigInt(10), b: NewBigInt(10), s: -2},
97 {x: New(1, -2), y: New(100, 1), a: NewBigInt(1), b: NewBigInt(100000), s: -2},
98 }
99 for _, tc := range tests {
100 t.Run(fmt.Sprintf("%s, %s", tc.x, tc.y), func(t *testing.T) {
101 a, b, s, err := upscale(tc.x, tc.y, new(BigInt))
102 if err != nil {
103 t.Fatal(err)
104 }
105 if a.Cmp(tc.a) != 0 {
106 t.Errorf("a: expected %s, got %s", tc.a, a)
107 }
108 if b.Cmp(tc.b) != 0 {
109 t.Errorf("b: expected %s, got %s", tc.b, b)
110 }
111 if s != tc.s {
112 t.Errorf("s: expected %d, got %d", tc.s, s)
113 }
114 })
115 }
116 }
117
118 func TestAdd(t *testing.T) {
119 tests := []struct {
120 x, y string
121 r string
122 }{
123 {x: "1", y: "10", r: "11"},
124 {x: "1", y: "1e1", r: "11"},
125 {x: "1e1", y: "1", r: "11"},
126 {x: ".1e1", y: "100e-1", r: "11.0"},
127 }
128 for _, tc := range tests {
129 t.Run(fmt.Sprintf("%s, %s", tc.x, tc.y), func(t *testing.T) {
130 x := newDecimal(t, testCtx, tc.x)
131 y := newDecimal(t, testCtx, tc.y)
132 d := new(Decimal)
133 _, err := testCtx.Add(d, x, y)
134 if err != nil {
135 t.Fatal(err)
136 }
137 s := d.String()
138 if s != tc.r {
139 t.Fatalf("expected: %s, got: %s", tc.r, s)
140 }
141 })
142 }
143 }
144
145 func TestCmp(t *testing.T) {
146 tests := []struct {
147 x, y string
148 c int
149 }{
150 {x: "1", y: "10", c: -1},
151 {x: "1", y: "1e1", c: -1},
152 {x: "1e1", y: "1", c: 1},
153 {x: ".1e1", y: "100e-1", c: -1},
154
155 {x: ".1e1", y: "100e-2", c: 0},
156 {x: "1", y: ".1e1", c: 0},
157 {x: "1", y: "1", c: 0},
158 }
159 for _, tc := range tests {
160 t.Run(fmt.Sprintf("%s, %s", tc.x, tc.y), func(t *testing.T) {
161 x := newDecimal(t, testCtx, tc.x)
162 y := newDecimal(t, testCtx, tc.y)
163 c := x.Cmp(y)
164 if c != tc.c {
165 t.Fatalf("expected: %d, got: %d", tc.c, c)
166 }
167 })
168 }
169 }
170
171 func TestModf(t *testing.T) {
172 tests := []struct {
173 x string
174 i string
175 f string
176 }{
177 {x: "1", i: "1", f: "0"},
178 {x: "1.0", i: "1", f: "0.0"},
179 {x: "1.0e1", i: "10", f: "0"},
180 {x: "1.0e2", i: "1.0E+2", f: "0"},
181 {x: "1.0e-1", i: "0", f: "0.10"},
182 {x: "1.0e-2", i: "0", f: "0.010"},
183 {x: "1.1", i: "1", f: "0.1"},
184 {x: "1234.56", i: "1234", f: "0.56"},
185 {x: "1234.56e2", i: "123456", f: "0"},
186 {x: "1234.56e4", i: "1.23456E+7", f: "0"},
187 {x: "1234.56e-2", i: "12", f: "0.3456"},
188 {x: "1234.56e-4", i: "0", f: "0.123456"},
189 {x: "1234.56e-6", i: "0", f: "0.00123456"},
190 {x: "123456e-8", i: "0", f: "0.00123456"},
191 {x: ".123456e8", i: "1.23456E+7", f: "0"},
192
193 {x: "-1", i: "-1", f: "-0"},
194 {x: "-1.0", i: "-1", f: "-0.0"},
195 {x: "-1.0e1", i: "-10", f: "-0"},
196 {x: "-1.0e2", i: "-1.0E+2", f: "-0"},
197 {x: "-1.0e-1", i: "-0", f: "-0.10"},
198 {x: "-1.0e-2", i: "-0", f: "-0.010"},
199 {x: "-1.1", i: "-1", f: "-0.1"},
200 {x: "-1234.56", i: "-1234", f: "-0.56"},
201 {x: "-1234.56e2", i: "-123456", f: "-0"},
202 {x: "-1234.56e4", i: "-1.23456E+7", f: "-0"},
203 {x: "-1234.56e-2", i: "-12", f: "-0.3456"},
204 {x: "-1234.56e-4", i: "-0", f: "-0.123456"},
205 {x: "-1234.56e-6", i: "-0", f: "-0.00123456"},
206 {x: "-123456e-8", i: "-0", f: "-0.00123456"},
207 {x: "-.123456e8", i: "-1.23456E+7", f: "-0"},
208 }
209 for _, tc := range tests {
210 t.Run(tc.x, func(t *testing.T) {
211 x := newDecimal(t, testCtx, tc.x)
212 integ, frac := new(Decimal), new(Decimal)
213 x.Modf(integ, frac)
214 if tc.i != integ.String() {
215 t.Fatalf("integ: expected: %s, got: %s", tc.i, integ)
216 }
217 if tc.f != frac.String() {
218 t.Fatalf("frac: expected: %s, got: %s", tc.f, frac)
219 }
220 a := new(Decimal)
221 if _, err := testCtx.Add(a, integ, frac); err != nil {
222 t.Fatal(err)
223 }
224 if a.Cmp(x) != 0 {
225 t.Fatalf("%s != %s", a, x)
226 }
227 if integ.Exponent < 0 {
228 t.Fatal(integ.Exponent)
229 }
230 if frac.Exponent > 0 {
231 t.Fatal(frac.Exponent)
232 }
233
234 integ2, frac2 := new(Decimal), new(Decimal)
235 x.Modf(integ2, nil)
236 x.Modf(nil, frac2)
237 if integ.CmpTotal(integ2) != 0 {
238 t.Fatalf("got %s, expected %s", integ2, integ)
239 }
240 if frac.CmpTotal(frac2) != 0 {
241 t.Fatalf("got %s, expected %s", frac2, frac)
242 }
243 })
244 }
245
246
247 a := new(Decimal)
248 a.Modf(nil, nil)
249 }
250
251 func TestInt64(t *testing.T) {
252 tests := []struct {
253 x string
254 i int64
255 err bool
256 }{
257 {x: "0.12e1", err: true},
258 {x: "0.1e1", i: 1},
259 {x: "10", i: 10},
260 {x: "12.3e3", i: 12300},
261 {x: "1e-1", err: true},
262 {x: "1e2", i: 100},
263 {x: "1", i: 1},
264 {x: "NaN", err: true},
265 {x: "Inf", err: true},
266 {x: "9223372036854775807", i: 9223372036854775807},
267 {x: "-9223372036854775808", i: -9223372036854775808},
268 {x: "9223372036854775808", err: true},
269 }
270 for _, tc := range tests {
271 t.Run(tc.x, func(t *testing.T) {
272 x := newDecimal(t, testCtx, tc.x)
273 i, err := x.Int64()
274 hasErr := err != nil
275 if tc.err != hasErr {
276 t.Fatalf("expected error: %v, got error: %v", tc.err, err)
277 }
278 if hasErr {
279 return
280 }
281 if i != tc.i {
282 t.Fatalf("expected: %v, got %v", tc.i, i)
283 }
284 })
285 }
286 }
287
288 func TestQuoErr(t *testing.T) {
289 tests := []struct {
290 x, y string
291 p uint32
292 err string
293 }{
294 {x: "1", y: "1", p: 0, err: errZeroPrecisionStr},
295 {x: "1", y: "0", p: 1, err: "division by zero"},
296 }
297 for _, tc := range tests {
298 c := testCtx.WithPrecision(tc.p)
299 x := newDecimal(t, testCtx, tc.x)
300 y := newDecimal(t, testCtx, tc.y)
301 d := new(Decimal)
302 _, err := c.Quo(d, x, y)
303 if err == nil {
304 t.Fatal("expected error")
305 }
306 if err.Error() != tc.err {
307 t.Fatalf("expected %s, got %s", tc.err, err)
308 }
309 }
310 }
311
312 func TestConditionString(t *testing.T) {
313 tests := map[Condition]string{
314 Overflow: "overflow",
315 Overflow | Underflow: "overflow, underflow",
316 Subnormal | Inexact: "inexact, subnormal",
317 }
318 for c, s := range tests {
319 t.Run(s, func(t *testing.T) {
320 cs := c.String()
321 if cs != s {
322 t.Errorf("expected %s; got %s", s, cs)
323 }
324 })
325 }
326 }
327
328 func TestFloat64(t *testing.T) {
329 tests := []float64{
330 0,
331 1,
332 -1,
333 math.MaxFloat32,
334 math.SmallestNonzeroFloat32,
335 math.MaxFloat64,
336 math.SmallestNonzeroFloat64,
337 }
338
339 for _, tc := range tests {
340 t.Run(fmt.Sprint(tc), func(t *testing.T) {
341 d := new(Decimal)
342 d.SetFloat64(tc)
343 f, err := d.Float64()
344 if err != nil {
345 t.Fatal(err)
346 }
347 if tc != f {
348 t.Fatalf("expected %v, got %v", tc, f)
349 }
350 })
351 }
352 }
353
354 func TestCeil(t *testing.T) {
355 tests := map[float64]int64{
356 0: 0,
357 -0.1: 0,
358 0.1: 1,
359 -0.9: 0,
360 0.9: 1,
361 -1: -1,
362 1: 1,
363 -1.1: -1,
364 1.1: 2,
365 }
366
367 for f, r := range tests {
368 t.Run(fmt.Sprint(f), func(t *testing.T) {
369 d, err := new(Decimal).SetFloat64(f)
370 if err != nil {
371 t.Fatal(err)
372 }
373 _, err = testCtx.Ceil(d, d)
374 if err != nil {
375 t.Fatal(err)
376 }
377 i, err := d.Int64()
378 if err != nil {
379 t.Fatal(err)
380 }
381 if i != r {
382 t.Fatalf("got %v, expected %v", i, r)
383 }
384 })
385 }
386 }
387
388 func TestFloor(t *testing.T) {
389 tests := map[float64]int64{
390 0: 0,
391 -0.1: -1,
392 0.1: 0,
393 -0.9: -1,
394 0.9: 0,
395 -1: -1,
396 1: 1,
397 -1.1: -2,
398 1.1: 1,
399 }
400
401 for f, r := range tests {
402 t.Run(fmt.Sprint(f), func(t *testing.T) {
403 d, err := new(Decimal).SetFloat64(f)
404 if err != nil {
405 t.Fatal(err)
406 }
407 _, err = testCtx.Floor(d, d)
408 if err != nil {
409 t.Fatal(err)
410 }
411 i, err := d.Int64()
412 if err != nil {
413 t.Fatal(err)
414 }
415 if i != r {
416 t.Fatalf("got %v, expected %v", i, r)
417 }
418 })
419 }
420 }
421
422 func TestFormat(t *testing.T) {
423 tests := map[string]struct {
424 e, E, f, g, G string
425 }{
426 "NaN": {},
427 "Infinity": {},
428 "-Infinity": {},
429 "sNaN": {},
430 "0": {
431 e: "0e+0",
432 E: "0E+0",
433 },
434 "-0": {
435 e: "-0e+0",
436 E: "-0E+0",
437 },
438 "0.0": {
439 e: "0e-1",
440 E: "0E-1",
441 },
442 "-0.0": {
443 e: "-0e-1",
444 E: "-0E-1",
445 },
446 "0E+2": {
447 e: "0e+2",
448 f: "000",
449 g: "0e+2",
450 },
451 "0E-9": {
452 e: "0e-9",
453 f: "0.000000000",
454 g: "0.000000000",
455 G: "0.000000000",
456 },
457 "0E-2000": {
458 e: "0e-2000",
459 f: "0." + strings.Repeat("0", 2000),
460 g: "0." + strings.Repeat("0", 2000),
461 G: "0." + strings.Repeat("0", 2000),
462 },
463 "0E-2001": {
464 e: "0e-2001",
465 f: "0." + strings.Repeat("0", 2001),
466 g: "0e-2001",
467 G: "0E-2001",
468 },
469 }
470 verbs := []string{"%e", "%E", "%f", "%g", "%G"}
471
472 for input, tc := range tests {
473 t.Run(input, func(t *testing.T) {
474 d, _, err := NewFromString(input)
475 if err != nil {
476 t.Fatal(err)
477 }
478 for i, s := range []string{tc.e, tc.E, tc.f, tc.g, tc.G} {
479 if s == "" {
480 s = input
481 }
482 v := verbs[i]
483 t.Run(v, func(t *testing.T) {
484 out := fmt.Sprintf(v, d)
485 if out != s {
486 t.Fatalf("expected %s, got %s", s, out)
487 }
488 })
489 }
490 })
491 }
492 }
493
494 func TestFormatFlags(t *testing.T) {
495 const stdD = "1.23E+56"
496 tests := []struct {
497 d string
498 fmt string
499 out string
500 }{
501 {
502 d: stdD,
503 fmt: "%3G",
504 out: "1.23E+56",
505 },
506 {
507 d: stdD,
508 fmt: "%010G",
509 out: "001.23E+56",
510 },
511 {
512 d: stdD,
513 fmt: "%10G",
514 out: " 1.23E+56",
515 },
516 {
517 d: stdD,
518 fmt: "%+G",
519 out: "+1.23E+56",
520 },
521 {
522 d: stdD,
523 fmt: "% G",
524 out: " 1.23E+56",
525 },
526 {
527 d: stdD,
528 fmt: "%-10G",
529 out: "1.23E+56 ",
530 },
531 {
532 d: stdD,
533 fmt: "%-010G",
534 out: "1.23E+56 ",
535 },
536 {
537 d: "nan",
538 fmt: "%-10G",
539 out: "NaN ",
540 },
541 {
542 d: "nan",
543 fmt: "%10G",
544 out: " NaN",
545 },
546 {
547 d: "nan",
548 fmt: "%010G",
549 out: " NaN",
550 },
551 {
552 d: "inf",
553 fmt: "%-10G",
554 out: "Infinity ",
555 },
556 {
557 d: "inf",
558 fmt: "%10G",
559 out: " Infinity",
560 },
561 {
562 d: "inf",
563 fmt: "%010G",
564 out: " Infinity",
565 },
566 {
567 d: "-inf",
568 fmt: "%-10G",
569 out: "-Infinity ",
570 },
571 {
572 d: "-inf",
573 fmt: "%10G",
574 out: " -Infinity",
575 },
576 {
577 d: "-inf",
578 fmt: "%010G",
579 out: " -Infinity",
580 },
581 {
582 d: "0",
583 fmt: "%d",
584 out: "%!d(*apd.Decimal=0)",
585 },
586 }
587 for _, tc := range tests {
588 t.Run(fmt.Sprintf("%s: %s", tc.d, tc.fmt), func(t *testing.T) {
589 d := newDecimal(t, &BaseContext, tc.d)
590 s := fmt.Sprintf(tc.fmt, d)
591 if s != tc.out {
592 t.Fatalf("expected %q, got %q", tc.out, s)
593 }
594 })
595 }
596 }
597
598 func TestContextSetStringt(t *testing.T) {
599 tests := []struct {
600 s string
601 c *Context
602 expect string
603 }{
604 {
605 s: "1.234",
606 c: &BaseContext,
607 expect: "1.234",
608 },
609 {
610 s: "1.234",
611 c: BaseContext.WithPrecision(2),
612 expect: "1.2",
613 },
614 }
615 for i, tc := range tests {
616 t.Run(fmt.Sprintf("%d: %s", i, tc.s), func(t *testing.T) {
617 d := new(Decimal)
618 if _, _, err := tc.c.SetString(d, tc.s); err != nil {
619 t.Fatal(err)
620 }
621 got := d.String()
622 if got != tc.expect {
623 t.Fatalf("expected: %s, got: %s", tc.expect, got)
624 }
625 })
626 }
627 }
628
629 func TestQuantize(t *testing.T) {
630 tests := []struct {
631 s string
632 e int32
633 expect string
634 }{
635 {
636 s: "1.00",
637 e: -1,
638 expect: "1.0",
639 },
640 {
641 s: "2.0",
642 e: -1,
643 expect: "2.0",
644 },
645 {
646 s: "3",
647 e: -1,
648 expect: "3.0",
649 },
650 {
651 s: "9.9999",
652 e: -2,
653 expect: "10.00",
654 },
655 }
656 c := BaseContext.WithPrecision(10)
657 for _, tc := range tests {
658 t.Run(fmt.Sprintf("%s: %d", tc.s, tc.e), func(t *testing.T) {
659 d, _, err := NewFromString(tc.s)
660 if err != nil {
661 t.Fatal(err)
662 }
663 if _, err := c.Quantize(d, d, tc.e); err != nil {
664 t.Fatal(err)
665 }
666 s := d.String()
667 if s != tc.expect {
668 t.Fatalf("expected: %s, got: %s", tc.expect, s)
669 }
670 })
671 }
672 }
673
674 func TestCmpOrder(t *testing.T) {
675 tests := []struct {
676 s string
677 order int
678 }{
679 {s: "-NaN", order: -4},
680 {s: "-sNaN", order: -3},
681 {s: "-Infinity", order: -2},
682 {s: "-127", order: -1},
683 {s: "-1.00", order: -1},
684 {s: "-1", order: -1},
685 {s: "-0.000", order: -1},
686 {s: "-0", order: -1},
687 {s: "0", order: 1},
688 {s: "1.2300", order: 1},
689 {s: "1.23", order: 1},
690 {s: "1E+9", order: 1},
691 {s: "Infinity", order: 2},
692 {s: "sNaN", order: 3},
693 {s: "NaN", order: 4},
694 }
695
696 for _, tc := range tests {
697 t.Run(tc.s, func(t *testing.T) {
698 d, _, err := NewFromString(tc.s)
699 if err != nil {
700 t.Fatal(err)
701 }
702 o := d.cmpOrder()
703 if o != tc.order {
704 t.Fatalf("got %d, expected %d", o, tc.order)
705 }
706 })
707 }
708 }
709
710 func TestIsZero(t *testing.T) {
711 tests := []struct {
712 s string
713 zero bool
714 }{
715 {s: "-NaN", zero: false},
716 {s: "-sNaN", zero: false},
717 {s: "-Infinity", zero: false},
718 {s: "-127", zero: false},
719 {s: "-1.00", zero: false},
720 {s: "-1", zero: false},
721 {s: "-0.000", zero: true},
722 {s: "-0", zero: true},
723 {s: "0", zero: true},
724 {s: "1.2300", zero: false},
725 {s: "1.23", zero: false},
726 {s: "1E+9", zero: false},
727 {s: "Infinity", zero: false},
728 {s: "sNaN", zero: false},
729 {s: "NaN", zero: false},
730 }
731
732 for _, tc := range tests {
733 t.Run(tc.s, func(t *testing.T) {
734 d, _, err := NewFromString(tc.s)
735 if err != nil {
736 t.Fatal(err)
737 }
738 z := d.IsZero()
739 if z != tc.zero {
740 t.Fatalf("got %v, expected %v", z, tc.zero)
741 }
742 })
743 }
744 }
745
746 func TestNeg(t *testing.T) {
747 tests := map[string]string{
748 "0": "0",
749 "-0": "0",
750 "-0.000": "0.000",
751 "-00.000100": "0.000100",
752 }
753
754 for tc, expect := range tests {
755 t.Run(tc, func(t *testing.T) {
756 d, _, err := NewFromString(tc)
757 if err != nil {
758 t.Fatal(err)
759 }
760 var z Decimal
761 z.Neg(d)
762 s := z.String()
763 if s != expect {
764 t.Fatalf("expected %s, got %s", expect, s)
765 }
766 })
767 }
768 }
769
770 func TestReduce(t *testing.T) {
771 tests := map[string]int{
772 "-0": 0,
773 "0": 0,
774 "0.0": 0,
775 "00": 0,
776 "0.00": 0,
777 "-01000": 3,
778 "01000": 3,
779 "-1": 0,
780 "1": 0,
781 "-10.000E4": 4,
782 "10.000E4": 4,
783 "-10.00": 3,
784 "10.00": 3,
785 "-10": 1,
786 "10": 1,
787 "-143200000000000000000000000000000000000000000000000000000000": 56,
788 "143200000000000000000000000000000000000000000000000000000000": 56,
789 "Inf": 0,
790 "NaN": 0,
791 }
792
793 for s, n := range tests {
794 t.Run(s, func(t *testing.T) {
795 d, _, err := NewFromString(s)
796 if err != nil {
797 t.Fatal(err)
798 }
799 _, got := d.Reduce(d)
800 if n != got {
801 t.Fatalf("got %v, expected %v", got, n)
802 }
803 })
804 }
805 }
806
807
808
809 func TestSizeof(t *testing.T) {
810
811 exp := map[int]map[string]uintptr{
812 32: {
813 "BigInt": 20,
814 "Decimal": 28,
815 "Context": 24,
816 },
817 64: {
818 "BigInt": 24,
819 "Decimal": 32,
820 "Context": 32,
821 },
822 }[bits.UintSize]
823
824 var b BigInt
825 if s := unsafe.Sizeof(b); s != exp["BigInt"] {
826 t.Errorf("sizeof(BigInt) changed: %d", s)
827 }
828 var d Decimal
829 if s := unsafe.Sizeof(d); s != exp["Decimal"] {
830 t.Errorf("sizeof(Decimal) changed: %d", s)
831 }
832 var c Context
833 if s := unsafe.Sizeof(c); s != exp["Context"] {
834 t.Errorf("sizeof(Context) changed: %d", s)
835 }
836 }
837
838
839
840
841 func TestSize(t *testing.T) {
842
843 exp := map[int]map[bool]map[string]uintptr{
844 32: {
845 true: {
846 "BigInt": 20,
847 "Decimal": 28,
848 },
849 false: {
850 "BigInt": 72,
851 "Decimal": 80,
852 },
853 },
854 64: {
855 true: {
856 "BigInt": 24,
857 "Decimal": 32,
858 },
859 false: {
860 "BigInt": 112,
861 "Decimal": 120,
862 },
863 },
864 }[bits.UintSize]
865
866 var d Decimal
867 if e, s := exp[true]["Decimal"], d.Size(); e != s {
868 t.Errorf("(*Decimal).Size() != %d: %d", e, s)
869 }
870 if e, s := exp[true]["BigInt"], d.Coeff.Size(); e != s {
871 t.Errorf("(*BigInt).Size() != %d: %d", e, s)
872 }
873
874 d.SetInt64(1234)
875 if e, s := exp[true]["Decimal"], d.Size(); e != s {
876 t.Errorf("(*Decimal).Size() != %d: %d", e, s)
877 }
878 if e, s := exp[true]["BigInt"], d.Coeff.Size(); e != s {
879 t.Errorf("(*BigInt).Size() != %d: %d", e, s)
880 }
881
882 if _, _, err := d.SetString("123456789123456789123456789.123456789123456789"); err != nil {
883 t.Fatal(err)
884 }
885 if d.Coeff.isInline() {
886
887 t.Fatal("BigInt inlined large value. Did inlineWords change?")
888 }
889 if e, s := exp[false]["Decimal"], d.Size(); e != s {
890 t.Errorf("(*Decimal).Size() != %d: %d", e, s)
891 }
892 if e, s := exp[false]["BigInt"], d.Coeff.Size(); e != s {
893 t.Errorf("(*BigInt).Size() != %d: %d", e, s)
894 }
895 }
896
897 func TestJSONEncoding(t *testing.T) {
898 var encodingTests = []string{
899 "0",
900 "1",
901 "2",
902 "10",
903 "1000",
904 "1234567890",
905 "298472983472983471903246121093472394872319615612417471234712061",
906 "0.0",
907 "NaN",
908 "Inf",
909 "123.456",
910 "1E1",
911 "1E-1",
912 "1.2E3",
913 }
914
915 for _, test := range encodingTests {
916 for _, sign := range []string{"", "+", "-"} {
917 x := sign + test
918 var tx Decimal
919 tx.SetString(x)
920 b, err := json.Marshal(&tx)
921 if err != nil {
922 t.Errorf("marshaling of %s failed: %s", &tx, err)
923 continue
924 }
925 var rx Decimal
926 if err := json.Unmarshal(b, &rx); err != nil {
927 t.Errorf("unmarshaling of %s failed: %s", &tx, err)
928 continue
929 }
930 if rx.CmpTotal(&tx) != 0 {
931 t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
932 }
933 }
934 }
935 }
936
View as plain text