1/*
2Copyright 2014 SAP SE
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package driver
18
19import (
20	"math/big"
21	"testing"
22)
23
24func TestDecimalInfo(t *testing.T) {
25	t.Logf("maximum decimal value %v", maxDecimal)
26	t.Logf("~log2(10): %f", lg10)
27}
28
29type testDigits10 struct {
30	x      *big.Int
31	digits int
32}
33
34var testDigits10Data = []*testDigits10{
35	&testDigits10{new(big.Int).SetInt64(0), 1},
36	&testDigits10{new(big.Int).SetInt64(1), 1},
37	&testDigits10{new(big.Int).SetInt64(9), 1},
38	&testDigits10{new(big.Int).SetInt64(10), 2},
39	&testDigits10{new(big.Int).SetInt64(99), 2},
40	&testDigits10{new(big.Int).SetInt64(100), 3},
41	&testDigits10{new(big.Int).SetInt64(999), 3},
42	&testDigits10{new(big.Int).SetInt64(1000), 4},
43	&testDigits10{new(big.Int).SetInt64(9999), 4},
44	&testDigits10{new(big.Int).SetInt64(10000), 5},
45	&testDigits10{new(big.Int).SetInt64(99999), 5},
46	&testDigits10{new(big.Int).SetInt64(100000), 6},
47	&testDigits10{new(big.Int).SetInt64(999999), 6},
48	&testDigits10{new(big.Int).SetInt64(1000000), 7},
49	&testDigits10{new(big.Int).SetInt64(9999999), 7},
50	&testDigits10{new(big.Int).SetInt64(10000000), 8},
51	&testDigits10{new(big.Int).SetInt64(99999999), 8},
52	&testDigits10{new(big.Int).SetInt64(100000000), 9},
53	&testDigits10{new(big.Int).SetInt64(999999999), 9},
54	&testDigits10{new(big.Int).SetInt64(1000000000), 10},
55	&testDigits10{new(big.Int).SetInt64(9999999999), 10},
56}
57
58func TestDigits10(t *testing.T) {
59	for i, d := range testDigits10Data {
60		digits := digits10(d.x)
61		if d.digits != digits {
62			t.Fatalf("value %d int %s digits %d - expected digits %d", i, d.x, digits, d.digits)
63		}
64	}
65}
66
67type testRat struct {
68	// in
69	x      *big.Rat
70	digits int
71	minExp int
72	maxExp int
73	// out
74	cmp *big.Int
75	neg bool
76	exp int
77	df  decFlags
78}
79
80var testRatData = []*testRat{
81	&testRat{new(big.Rat).SetFrac64(0, 1), 3, -2, 2, new(big.Int).SetInt64(0), false, 0, 0},                              //convert 0
82	&testRat{new(big.Rat).SetFrac64(1, 1), 3, -2, 2, new(big.Int).SetInt64(1), false, 0, 0},                              //convert 1
83	&testRat{new(big.Rat).SetFrac64(1, 10), 3, -2, 2, new(big.Int).SetInt64(1), false, -1, 0},                            //convert 1/10
84	&testRat{new(big.Rat).SetFrac64(1, 99), 3, -2, 2, new(big.Int).SetInt64(1), false, -2, dfNotExact},                   //convert 1/99
85	&testRat{new(big.Rat).SetFrac64(1, 100), 3, -2, 2, new(big.Int).SetInt64(1), false, -2, 0},                           //convert 1/100
86	&testRat{new(big.Rat).SetFrac64(1, 1000), 3, -2, 2, new(big.Int).SetInt64(1), false, -3, dfUnderflow},                //convert 1/1000
87	&testRat{new(big.Rat).SetFrac64(10, 1), 3, -2, 2, new(big.Int).SetInt64(1), false, 1, 0},                             //convert 10
88	&testRat{new(big.Rat).SetFrac64(100, 1), 3, -2, 2, new(big.Int).SetInt64(1), false, 2, 0},                            //convert 100
89	&testRat{new(big.Rat).SetFrac64(1000, 1), 3, -2, 2, new(big.Int).SetInt64(10), false, 2, 0},                          //convert 1000
90	&testRat{new(big.Rat).SetFrac64(10000, 1), 3, -2, 2, new(big.Int).SetInt64(100), false, 2, 0},                        //convert 10000
91	&testRat{new(big.Rat).SetFrac64(100000, 1), 3, -2, 2, new(big.Int).SetInt64(100), false, 3, dfOverflow},              //convert 100000
92	&testRat{new(big.Rat).SetFrac64(999999, 1), 3, -2, 2, new(big.Int).SetInt64(100), false, 4, dfNotExact | dfOverflow}, //convert 999999
93	&testRat{new(big.Rat).SetFrac64(99999, 1), 3, -2, 2, new(big.Int).SetInt64(100), false, 3, dfNotExact | dfOverflow},  //convert 99999
94	&testRat{new(big.Rat).SetFrac64(9999, 1), 3, -2, 2, new(big.Int).SetInt64(100), false, 2, dfNotExact},                //convert 9999
95	&testRat{new(big.Rat).SetFrac64(99950, 1), 3, -2, 2, new(big.Int).SetInt64(100), false, 3, dfNotExact | dfOverflow},  //convert 99950
96	&testRat{new(big.Rat).SetFrac64(99949, 1), 3, -2, 2, new(big.Int).SetInt64(999), false, 2, dfNotExact},               //convert 99949
97
98	&testRat{new(big.Rat).SetFrac64(1, 3), 5, -5, 5, new(big.Int).SetInt64(33333), false, -5, dfNotExact}, //convert 1/3
99	&testRat{new(big.Rat).SetFrac64(2, 3), 5, -5, 5, new(big.Int).SetInt64(66667), false, -5, dfNotExact}, //convert 2/3
100	&testRat{new(big.Rat).SetFrac64(11, 2), 5, -5, 5, new(big.Int).SetInt64(55), false, -1, 0},            //convert 11/2
101
102}
103
104func TestConvertRat(t *testing.T) {
105	m := new(big.Int)
106
107	for i := 0; i < 1; i++ { // use for performance tests
108		for j, d := range testRatData {
109			neg, exp, df := convertRatToDecimal(d.x, m, d.digits, d.minExp, d.maxExp)
110			if m.Cmp(d.cmp) != 0 || neg != d.neg || exp != d.exp || df != d.df {
111				t.Fatalf("converted %d value m %s neg %t exp %d df %b - expected m %s neg %t exp %d df %b", j, m, neg, exp, df, d.cmp, d.neg, d.exp, d.df)
112			}
113		}
114	}
115}
116