github.com/XiaoMi/Gaea@v1.2.5/parser/tidb-types/mydecimal_test.go (about)

     1  // Copyright 2016 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package types
    15  
    16  import (
    17  	"strings"
    18  	"testing"
    19  
    20  	. "github.com/pingcap/check"
    21  )
    22  
    23  var _ = Suite(&testMyDecimalSuite{})
    24  
    25  type testMyDecimalSuite struct {
    26  }
    27  
    28  func (s *testMyDecimalSuite) TestFromInt(c *C) {
    29  	tests := []struct {
    30  		input  int64
    31  		output string
    32  	}{
    33  		{-12345, "-12345"},
    34  		{-1, "-1"},
    35  		{1, "1"},
    36  		{-9223372036854775807, "-9223372036854775807"},
    37  		{-9223372036854775808, "-9223372036854775808"},
    38  	}
    39  	for _, tt := range tests {
    40  		dec := NewDecFromInt(tt.input)
    41  		str := dec.ToString()
    42  		c.Check(string(str), Equals, tt.output)
    43  	}
    44  }
    45  
    46  func (s *testMyDecimalSuite) TestFromUint(c *C) {
    47  	tests := []struct {
    48  		input  uint64
    49  		output string
    50  	}{
    51  		{12345, "12345"},
    52  		{0, "0"},
    53  		{18446744073709551615, "18446744073709551615"},
    54  	}
    55  	for _, tt := range tests {
    56  		var dec MyDecimal
    57  		dec.FromUint(tt.input)
    58  		str := dec.ToString()
    59  		c.Check(string(str), Equals, tt.output)
    60  	}
    61  }
    62  
    63  func (s *testMyDecimalSuite) TestToInt(c *C) {
    64  	tests := []struct {
    65  		input  string
    66  		output int64
    67  		err    error
    68  	}{
    69  		{"18446744073709551615", 9223372036854775807, ErrOverflow},
    70  		{"-1", -1, nil},
    71  		{"1", 1, nil},
    72  		{"-1.23", -1, ErrTruncated},
    73  		{"-9223372036854775807", -9223372036854775807, nil},
    74  		{"-9223372036854775808", -9223372036854775808, nil},
    75  		{"9223372036854775808", 9223372036854775807, ErrOverflow},
    76  		{"-9223372036854775809", -9223372036854775808, ErrOverflow},
    77  	}
    78  	for _, tt := range tests {
    79  		var dec MyDecimal
    80  		dec.FromString([]byte(tt.input))
    81  		result, ec := dec.ToInt()
    82  		c.Check(ec, Equals, tt.err)
    83  		c.Check(result, Equals, tt.output)
    84  	}
    85  }
    86  
    87  func (s *testMyDecimalSuite) TestToUint(c *C) {
    88  	tests := []struct {
    89  		input  string
    90  		output uint64
    91  		err    error
    92  	}{
    93  		{"12345", 12345, nil},
    94  		{"0", 0, nil},
    95  		/* ULLONG_MAX = 18446744073709551615ULL */
    96  		{"18446744073709551615", 18446744073709551615, nil},
    97  		{"18446744073709551616", 18446744073709551615, ErrOverflow},
    98  		{"-1", 0, ErrOverflow},
    99  		{"1.23", 1, ErrTruncated},
   100  		{"9999999999999999999999999.000", 18446744073709551615, ErrOverflow},
   101  	}
   102  	for _, tt := range tests {
   103  		var dec MyDecimal
   104  		dec.FromString([]byte(tt.input))
   105  		result, ec := dec.ToUint()
   106  		c.Check(ec, Equals, tt.err)
   107  		c.Check(result, Equals, tt.output)
   108  	}
   109  }
   110  
   111  func (s *testMyDecimalSuite) TestFromFloat(c *C) {
   112  	tests := []struct {
   113  		s string
   114  		f float64
   115  	}{
   116  		{"12345", 12345},
   117  		{"123.45", 123.45},
   118  		{"-123.45", -123.45},
   119  		{"0.00012345000098765", 0.00012345000098765},
   120  		{"1234500009876.5", 1234500009876.5},
   121  	}
   122  	for _, tt := range tests {
   123  		dec := NewDecFromFloatForTest(tt.f)
   124  		str := dec.ToString()
   125  		c.Check(string(str), Equals, tt.s)
   126  	}
   127  }
   128  
   129  func (s *testMyDecimalSuite) TestToFloat(c *C) {
   130  	tests := []struct {
   131  		s string
   132  		f float64
   133  	}{
   134  		{"12345", 12345},
   135  		{"123.45", 123.45},
   136  		{"-123.45", -123.45},
   137  		{"0.00012345000098765", 0.00012345000098765},
   138  		{"1234500009876.5", 1234500009876.5},
   139  	}
   140  	for _, ca := range tests {
   141  		var dec MyDecimal
   142  		dec.FromString([]byte(ca.s))
   143  		f, err := dec.ToFloat64()
   144  		c.Check(err, IsNil)
   145  		c.Check(f, Equals, ca.f)
   146  	}
   147  }
   148  
   149  func (s *testMyDecimalSuite) TestToHashKey(c *C) {
   150  	tests := []struct {
   151  		numbers []string
   152  	}{
   153  		{[]string{"1.1", "1.1000", "1.1000000", "1.10000000000", "01.1", "0001.1", "001.1000000"}},
   154  		{[]string{"-1.1", "-1.1000", "-1.1000000", "-1.10000000000", "-01.1", "-0001.1", "-001.1000000"}},
   155  		{[]string{".1", "0.1", "000000.1", ".10000", "0000.10000", "000000000000000000.1"}},
   156  		{[]string{"0", "0000", ".0", ".00000", "00000.00000", "-0", "-0000", "-.0", "-.00000", "-00000.00000"}},
   157  		{[]string{".123456789123456789", ".1234567891234567890", ".12345678912345678900", ".123456789123456789000", ".1234567891234567890000", "0.123456789123456789",
   158  			".1234567891234567890000000000", "0000000.123456789123456789000"}},
   159  		{[]string{"12345", "012345", "0012345", "0000012345", "0000000012345", "00000000000012345", "12345.", "12345.00", "12345.000000000", "000012345.0000"}},
   160  		{[]string{"123E5", "12300000", "00123E5", "000000123E5", "12300000.00000000"}},
   161  		{[]string{"123E-2", "1.23", "00000001.23", "1.2300000000000000", "000000001.23000000000000"}},
   162  	}
   163  	for _, ca := range tests {
   164  		keys := make([]string, 0, len(ca.numbers))
   165  		for _, num := range ca.numbers {
   166  			var dec MyDecimal
   167  			c.Check(dec.FromString([]byte(num)), IsNil)
   168  			key, err := dec.ToHashKey()
   169  			c.Check(err, IsNil)
   170  			keys = append(keys, string(key))
   171  		}
   172  
   173  		for i := 1; i < len(keys); i++ {
   174  			c.Check(keys[0], Equals, keys[i])
   175  		}
   176  	}
   177  
   178  	binTests := []struct {
   179  		hashNumbers []string
   180  		binNumbers  []string
   181  	}{
   182  		{[]string{"1.1", "1.1000", "1.1000000", "1.10000000000", "01.1", "0001.1", "001.1000000"},
   183  			[]string{"1.1", "0001.1", "01.1"}},
   184  		{[]string{"-1.1", "-1.1000", "-1.1000000", "-1.10000000000", "-01.1", "-0001.1", "-001.1000000"},
   185  			[]string{"-1.1", "-0001.1", "-01.1"}},
   186  		{[]string{".1", "0.1", "000000.1", ".10000", "0000.10000", "000000000000000000.1"},
   187  			[]string{".1", "0.1", "000000.1", "00.1"}},
   188  		{[]string{"0", "0000", ".0", ".00000", "00000.00000", "-0", "-0000", "-.0", "-.00000", "-00000.00000"},
   189  			[]string{"0", "0000", "00", "-0", "-00", "-000000"}},
   190  		{[]string{".123456789123456789", ".1234567891234567890", ".12345678912345678900", ".123456789123456789000", ".1234567891234567890000", "0.123456789123456789",
   191  			".1234567891234567890000000000", "0000000.123456789123456789000"},
   192  			[]string{".123456789123456789", "0.123456789123456789", "0000.123456789123456789", "0000000.123456789123456789"}},
   193  		{[]string{"12345", "012345", "0012345", "0000012345", "0000000012345", "00000000000012345", "12345.", "12345.00", "12345.000000000", "000012345.0000"},
   194  			[]string{"12345", "012345", "000012345", "000000000000012345"}},
   195  		{[]string{"123E5", "12300000", "00123E5", "000000123E5", "12300000.00000000"},
   196  			[]string{"12300000", "123E5", "00123E5", "0000000000123E5"}},
   197  		{[]string{"123E-2", "1.23", "00000001.23", "1.2300000000000000", "000000001.23000000000000"},
   198  			[]string{"123E-2", "1.23", "000001.23", "0000000000001.23"}},
   199  	}
   200  	for _, ca := range binTests {
   201  		keys := make([]string, 0, len(ca.hashNumbers)+len(ca.binNumbers))
   202  		for _, num := range ca.hashNumbers {
   203  			var dec MyDecimal
   204  			c.Check(dec.FromString([]byte(num)), IsNil)
   205  			key, err := dec.ToHashKey()
   206  			c.Check(err, IsNil)
   207  			keys = append(keys, string(key))
   208  		}
   209  		for _, num := range ca.binNumbers {
   210  			var dec MyDecimal
   211  			c.Check(dec.FromString([]byte(num)), IsNil)
   212  			prec, frac := dec.PrecisionAndFrac() // remove leading zeros but trailing zeros remain
   213  			key, err := dec.ToBin(prec, frac)
   214  			c.Check(err, IsNil)
   215  			keys = append(keys, string(key))
   216  		}
   217  
   218  		for i := 1; i < len(keys); i++ {
   219  			c.Check(keys[0], Equals, keys[i])
   220  		}
   221  	}
   222  }
   223  
   224  func (s *testMyDecimalSuite) TestRemoveTrailingZeros(c *C) {
   225  	tests := []string{
   226  		"0", "0.0", ".0", ".00000000", "0.0000", "0000", "0000.0", "0000.000",
   227  		"-0", "-0.0", "-.0", "-.00000000", "-0.0000", "-0000", "-0000.0", "-0000.000",
   228  		"123123123", "213123.", "21312.000", "21321.123", "213.1230000", "213123.000123000",
   229  		"-123123123", "-213123.", "-21312.000", "-21321.123", "-213.1230000", "-213123.000123000",
   230  		"123E5", "12300E-5", "0.00100E1", "0.001230E-3",
   231  		"123987654321.123456789000", "000000000123", "123456789.987654321", "999.999000",
   232  	}
   233  	for _, ca := range tests {
   234  		var dec MyDecimal
   235  		c.Check(dec.FromString([]byte(ca)), IsNil)
   236  
   237  		// calculate the number of digits after point but trailing zero
   238  		digitsFracExp := 0
   239  		str := string(dec.ToString())
   240  		point := strings.Index(str, ".")
   241  		if point != -1 {
   242  			pos := len(str) - 1
   243  			for pos > point {
   244  				if str[pos] != '0' {
   245  					break
   246  				}
   247  				pos--
   248  			}
   249  			digitsFracExp = pos - point
   250  		}
   251  
   252  		_, digitsFrac := dec.removeTrailingZeros()
   253  		c.Check(digitsFrac, Equals, digitsFracExp)
   254  	}
   255  }
   256  
   257  func (s *testMyDecimalSuite) TestShift(c *C) {
   258  	type tcase struct {
   259  		input  string
   260  		shift  int
   261  		output string
   262  		err    error
   263  	}
   264  	var dotest = func(c *C, tests []tcase) {
   265  		for _, ca := range tests {
   266  			var dec MyDecimal
   267  			err := dec.FromString([]byte(ca.input))
   268  			c.Check(err, IsNil)
   269  			origin := dec
   270  			err = dec.Shift(ca.shift)
   271  			c.Check(err, Equals, ca.err)
   272  			result := dec.ToString()
   273  			c.Check(string(result), Equals, ca.output, Commentf("origin:%s\ndec:%s", origin.String(), string(result)))
   274  		}
   275  	}
   276  	wordBufLen = maxWordBufLen
   277  	tests := []tcase{
   278  		{"123.123", 1, "1231.23", nil},
   279  		{"123457189.123123456789000", 1, "1234571891.23123456789", nil},
   280  		{"123457189.123123456789000", 8, "12345718912312345.6789", nil},
   281  		{"123457189.123123456789000", 9, "123457189123123456.789", nil},
   282  		{"123457189.123123456789000", 10, "1234571891231234567.89", nil},
   283  		{"123457189.123123456789000", 17, "12345718912312345678900000", nil},
   284  		{"123457189.123123456789000", 18, "123457189123123456789000000", nil},
   285  		{"123457189.123123456789000", 19, "1234571891231234567890000000", nil},
   286  		{"123457189.123123456789000", 26, "12345718912312345678900000000000000", nil},
   287  		{"123457189.123123456789000", 27, "123457189123123456789000000000000000", nil},
   288  		{"123457189.123123456789000", 28, "1234571891231234567890000000000000000", nil},
   289  		{"000000000000000000000000123457189.123123456789000", 26, "12345718912312345678900000000000000", nil},
   290  		{"00000000123457189.123123456789000", 27, "123457189123123456789000000000000000", nil},
   291  		{"00000000000000000123457189.123123456789000", 28, "1234571891231234567890000000000000000", nil},
   292  		{"123", 1, "1230", nil},
   293  		{"123", 10, "1230000000000", nil},
   294  		{".123", 1, "1.23", nil},
   295  		{".123", 10, "1230000000", nil},
   296  		{".123", 14, "12300000000000", nil},
   297  		{"000.000", 1000, "0", nil},
   298  		{"000.", 1000, "0", nil},
   299  		{".000", 1000, "0", nil},
   300  		{"1", 1000, "1", ErrOverflow},
   301  		{"123.123", -1, "12.3123", nil},
   302  		{"123987654321.123456789000", -1, "12398765432.1123456789", nil},
   303  		{"123987654321.123456789000", -2, "1239876543.21123456789", nil},
   304  		{"123987654321.123456789000", -3, "123987654.321123456789", nil},
   305  		{"123987654321.123456789000", -8, "1239.87654321123456789", nil},
   306  		{"123987654321.123456789000", -9, "123.987654321123456789", nil},
   307  		{"123987654321.123456789000", -10, "12.3987654321123456789", nil},
   308  		{"123987654321.123456789000", -11, "1.23987654321123456789", nil},
   309  		{"123987654321.123456789000", -12, "0.123987654321123456789", nil},
   310  		{"123987654321.123456789000", -13, "0.0123987654321123456789", nil},
   311  		{"123987654321.123456789000", -14, "0.00123987654321123456789", nil},
   312  		{"00000087654321.123456789000", -14, "0.00000087654321123456789", nil},
   313  	}
   314  	dotest(c, tests)
   315  	wordBufLen = 2
   316  	tests = []tcase{
   317  		{"123.123", -2, "1.23123", nil},
   318  		{"123.123", -3, "0.123123", nil},
   319  		{"123.123", -6, "0.000123123", nil},
   320  		{"123.123", -7, "0.0000123123", nil},
   321  		{"123.123", -15, "0.000000000000123123", nil},
   322  		{"123.123", -16, "0.000000000000012312", ErrTruncated},
   323  		{"123.123", -17, "0.000000000000001231", ErrTruncated},
   324  		{"123.123", -18, "0.000000000000000123", ErrTruncated},
   325  		{"123.123", -19, "0.000000000000000012", ErrTruncated},
   326  		{"123.123", -20, "0.000000000000000001", ErrTruncated},
   327  		{"123.123", -21, "0", ErrTruncated},
   328  		{".000000000123", -1, "0.0000000000123", nil},
   329  		{".000000000123", -6, "0.000000000000000123", nil},
   330  		{".000000000123", -7, "0.000000000000000012", ErrTruncated},
   331  		{".000000000123", -8, "0.000000000000000001", ErrTruncated},
   332  		{".000000000123", -9, "0", ErrTruncated},
   333  		{".000000000123", 1, "0.00000000123", nil},
   334  		{".000000000123", 8, "0.0123", nil},
   335  		{".000000000123", 9, "0.123", nil},
   336  		{".000000000123", 10, "1.23", nil},
   337  		{".000000000123", 17, "12300000", nil},
   338  		{".000000000123", 18, "123000000", nil},
   339  		{".000000000123", 19, "1230000000", nil},
   340  		{".000000000123", 20, "12300000000", nil},
   341  		{".000000000123", 21, "123000000000", nil},
   342  		{".000000000123", 22, "1230000000000", nil},
   343  		{".000000000123", 23, "12300000000000", nil},
   344  		{".000000000123", 24, "123000000000000", nil},
   345  		{".000000000123", 25, "1230000000000000", nil},
   346  		{".000000000123", 26, "12300000000000000", nil},
   347  		{".000000000123", 27, "123000000000000000", nil},
   348  		{".000000000123", 28, "0.000000000123", ErrOverflow},
   349  		{"123456789.987654321", -1, "12345678.998765432", ErrTruncated},
   350  		{"123456789.987654321", -2, "1234567.899876543", ErrTruncated},
   351  		{"123456789.987654321", -8, "1.234567900", ErrTruncated},
   352  		{"123456789.987654321", -9, "0.123456789987654321", nil},
   353  		{"123456789.987654321", -10, "0.012345678998765432", ErrTruncated},
   354  		{"123456789.987654321", -17, "0.000000001234567900", ErrTruncated},
   355  		{"123456789.987654321", -18, "0.000000000123456790", ErrTruncated},
   356  		{"123456789.987654321", -19, "0.000000000012345679", ErrTruncated},
   357  		{"123456789.987654321", -26, "0.000000000000000001", ErrTruncated},
   358  		{"123456789.987654321", -27, "0", ErrTruncated},
   359  		{"123456789.987654321", 1, "1234567900", ErrTruncated},
   360  		{"123456789.987654321", 2, "12345678999", ErrTruncated},
   361  		{"123456789.987654321", 4, "1234567899877", ErrTruncated},
   362  		{"123456789.987654321", 8, "12345678998765432", ErrTruncated},
   363  		{"123456789.987654321", 9, "123456789987654321", nil},
   364  		{"123456789.987654321", 10, "123456789.987654321", ErrOverflow},
   365  		{"123456789.987654321", 0, "123456789.987654321", nil},
   366  	}
   367  	dotest(c, tests)
   368  	wordBufLen = maxWordBufLen
   369  }
   370  
   371  func (s *testMyDecimalSuite) TestRoundWithHalfEven(c *C) {
   372  	tests := []struct {
   373  		input  string
   374  		scale  int
   375  		output string
   376  		err    error
   377  	}{
   378  		{"123456789.987654321", 1, "123456790.0", nil},
   379  		{"15.1", 0, "15", nil},
   380  		{"15.5", 0, "16", nil},
   381  		{"15.9", 0, "16", nil},
   382  		{"-15.1", 0, "-15", nil},
   383  		{"-15.5", 0, "-16", nil},
   384  		{"-15.9", 0, "-16", nil},
   385  		{"15.1", 1, "15.1", nil},
   386  		{"-15.1", 1, "-15.1", nil},
   387  		{"15.17", 1, "15.2", nil},
   388  		{"15.4", -1, "20", nil},
   389  		{"-15.4", -1, "-20", nil},
   390  		{"5.4", -1, "10", nil},
   391  		{".999", 0, "1", nil},
   392  		{"999999999", -9, "1000000000", nil},
   393  	}
   394  
   395  	for _, ca := range tests {
   396  		var dec MyDecimal
   397  		dec.FromString([]byte(ca.input))
   398  		var rounded MyDecimal
   399  		err := dec.Round(&rounded, ca.scale, ModeHalfEven)
   400  		c.Check(err, Equals, ca.err)
   401  		result := rounded.ToString()
   402  		c.Check(string(result), Equals, ca.output)
   403  	}
   404  }
   405  
   406  func (s *testMyDecimalSuite) TestRoundWithTruncate(c *C) {
   407  	tests := []struct {
   408  		input  string
   409  		scale  int
   410  		output string
   411  		err    error
   412  	}{
   413  		{"123456789.987654321", 1, "123456789.9", nil},
   414  		{"15.1", 0, "15", nil},
   415  		{"15.5", 0, "15", nil},
   416  		{"15.9", 0, "15", nil},
   417  		{"-15.1", 0, "-15", nil},
   418  		{"-15.5", 0, "-15", nil},
   419  		{"-15.9", 0, "-15", nil},
   420  		{"15.1", 1, "15.1", nil},
   421  		{"-15.1", 1, "-15.1", nil},
   422  		{"15.17", 1, "15.1", nil},
   423  		{"15.4", -1, "10", nil},
   424  		{"-15.4", -1, "-10", nil},
   425  		{"5.4", -1, "0", nil},
   426  		{".999", 0, "0", nil},
   427  		{"999999999", -9, "0", nil},
   428  	}
   429  	for _, ca := range tests {
   430  		var dec MyDecimal
   431  		dec.FromString([]byte(ca.input))
   432  		var rounded MyDecimal
   433  		err := dec.Round(&rounded, ca.scale, ModeTruncate)
   434  		c.Check(err, Equals, ca.err)
   435  		result := rounded.ToString()
   436  		c.Check(string(result), Equals, ca.output)
   437  	}
   438  }
   439  
   440  func (s *testMyDecimalSuite) TestRoundWithCeil(c *C) {
   441  	tests := []struct {
   442  		input  string
   443  		scale  int
   444  		output string
   445  		err    error
   446  	}{
   447  		{"123456789.987654321", 1, "123456790.0", nil},
   448  		{"15.1", 0, "16", nil},
   449  		{"15.5", 0, "16", nil},
   450  		{"15.9", 0, "16", nil},
   451  		//TODO:fix me
   452  		{"-15.1", 0, "-16", nil},
   453  		{"-15.5", 0, "-16", nil},
   454  		{"-15.9", 0, "-16", nil},
   455  		{"15.1", 1, "15.1", nil},
   456  		{"-15.1", 1, "-15.1", nil},
   457  		{"15.17", 1, "15.2", nil},
   458  		{"15.4", -1, "20", nil},
   459  		{"-15.4", -1, "-20", nil},
   460  		{"5.4", -1, "10", nil},
   461  		{".999", 0, "1", nil},
   462  		{"999999999", -9, "1000000000", nil},
   463  	}
   464  	for _, ca := range tests {
   465  		var dec MyDecimal
   466  		dec.FromString([]byte(ca.input))
   467  		var rounded MyDecimal
   468  		err := dec.Round(&rounded, ca.scale, modeCeiling)
   469  		c.Check(err, Equals, ca.err)
   470  		result := rounded.ToString()
   471  		c.Check(string(result), Equals, ca.output)
   472  	}
   473  }
   474  
   475  func (s *testMyDecimalSuite) TestFromString(c *C) {
   476  	type tcase struct {
   477  		input  string
   478  		output string
   479  		err    error
   480  	}
   481  	tests := []tcase{
   482  		{"12345", "12345", nil},
   483  		{"12345.", "12345", nil},
   484  		{"123.45.", "123.45", nil},
   485  		{"-123.45.", "-123.45", nil},
   486  		{".00012345000098765", "0.00012345000098765", nil},
   487  		{".12345000098765", "0.12345000098765", nil},
   488  		{"-.000000012345000098765", "-0.000000012345000098765", nil},
   489  		{"1234500009876.5", "1234500009876.5", nil},
   490  		{"123E5", "12300000", nil},
   491  		{"123E-2", "1.23", nil},
   492  		{"1e1073741823", "999999999999999999999999999999999999999999999999999999999999999999999999999999999", ErrOverflow},
   493  		{"-1e1073741823", "-999999999999999999999999999999999999999999999999999999999999999999999999999999999", ErrOverflow},
   494  		{"1e18446744073709551620", "0", ErrBadNumber},
   495  		{"1e", "1", ErrTruncated},
   496  		{"1e001", "10", nil},
   497  		{"1e00", "1", nil},
   498  		{"1eabc", "1", ErrTruncated},
   499  		{"1e 1dddd ", "10", ErrTruncated},
   500  		{"1e - 1", "1", ErrTruncated},
   501  		{"1e -1", "0.1", nil},
   502  	}
   503  	for _, ca := range tests {
   504  		var dec MyDecimal
   505  		err := dec.FromString([]byte(ca.input))
   506  		c.Check(err, Equals, ca.err, Commentf("input: %s", ca.input))
   507  		result := dec.ToString()
   508  		c.Check(string(result), Equals, ca.output, Commentf("dec:%s", dec.String()))
   509  	}
   510  	wordBufLen = 1
   511  	tests = []tcase{
   512  		{"123450000098765", "98765", ErrOverflow},
   513  		{"123450.000098765", "123450", ErrTruncated},
   514  	}
   515  	for _, ca := range tests {
   516  		var dec MyDecimal
   517  		err := dec.FromString([]byte(ca.input))
   518  		c.Check(err, Equals, ca.err)
   519  		result := dec.ToString()
   520  		c.Check(string(result), Equals, ca.output, Commentf("dec:%s", dec.String()))
   521  	}
   522  	wordBufLen = maxWordBufLen
   523  }
   524  
   525  func (s *testMyDecimalSuite) TestToString(c *C) {
   526  	type tcase struct {
   527  		input  string
   528  		output string
   529  	}
   530  	tests := []tcase{
   531  		{"123.123", "123.123"},
   532  		{"123.1230", "123.1230"},
   533  		{"00123.123", "123.123"},
   534  	}
   535  	for _, ca := range tests {
   536  		var dec MyDecimal
   537  		dec.FromString([]byte(ca.input))
   538  		result := dec.ToString()
   539  		c.Check(string(result), Equals, ca.output)
   540  	}
   541  }
   542  
   543  func (s *testMyDecimalSuite) TestToBinFromBin(c *C) {
   544  	type tcase struct {
   545  		input     string
   546  		precision int
   547  		frac      int
   548  		output    string
   549  		err       error
   550  	}
   551  	tests := []tcase{
   552  		{"-10.55", 4, 2, "-10.55", nil},
   553  		{"0.0123456789012345678912345", 30, 25, "0.0123456789012345678912345", nil},
   554  		{"12345", 5, 0, "12345", nil},
   555  		{"12345", 10, 3, "12345.000", nil},
   556  		{"123.45", 10, 3, "123.450", nil},
   557  		{"-123.45", 20, 10, "-123.4500000000", nil},
   558  		{".00012345000098765", 15, 14, "0.00012345000098", ErrTruncated},
   559  		{".00012345000098765", 22, 20, "0.00012345000098765000", nil},
   560  		{".12345000098765", 30, 20, "0.12345000098765000000", nil},
   561  		{"-.000000012345000098765", 30, 20, "-0.00000001234500009876", ErrTruncated},
   562  		{"1234500009876.5", 30, 5, "1234500009876.50000", nil},
   563  		{"111111111.11", 10, 2, "11111111.11", ErrOverflow},
   564  		{"000000000.01", 7, 3, "0.010", nil},
   565  		{"123.4", 10, 2, "123.40", nil},
   566  		{"1000", 3, 0, "0", ErrOverflow},
   567  	}
   568  	for _, ca := range tests {
   569  		var dec MyDecimal
   570  		err := dec.FromString([]byte(ca.input))
   571  		c.Assert(err, IsNil)
   572  		buf, err := dec.ToBin(ca.precision, ca.frac)
   573  		c.Assert(err, Equals, ca.err, Commentf(ca.input))
   574  		var dec2 MyDecimal
   575  		_, err = dec2.FromBin(buf, ca.precision, ca.frac)
   576  		c.Assert(err, IsNil)
   577  		str := dec2.ToString()
   578  		c.Assert(string(str), Equals, ca.output)
   579  	}
   580  	var dec MyDecimal
   581  	dec.FromInt(1)
   582  	errTests := []struct {
   583  		prec int
   584  		frac int
   585  	}{
   586  		{82, 1},
   587  		{-1, 1},
   588  		{10, 31},
   589  		{10, -1},
   590  	}
   591  	for _, tt := range errTests {
   592  		_, err := dec.ToBin(tt.prec, tt.frac)
   593  		c.Assert(ErrBadNumber.Equal(err), IsTrue)
   594  	}
   595  }
   596  
   597  func (s *testMyDecimalSuite) TestCompare(c *C) {
   598  	type tcase struct {
   599  		a   string
   600  		b   string
   601  		cmp int
   602  	}
   603  	tests := []tcase{
   604  		{"12", "13", -1},
   605  		{"13", "12", 1},
   606  		{"-10", "10", -1},
   607  		{"10", "-10", 1},
   608  		{"-12", "-13", 1},
   609  		{"0", "12", -1},
   610  		{"-10", "0", -1},
   611  		{"4", "4", 0},
   612  		{"-1.1", "-1.2", 1},
   613  		{"1.2", "1.1", 1},
   614  		{"1.1", "1.2", -1},
   615  	}
   616  	for _, tt := range tests {
   617  		var a, b MyDecimal
   618  		a.FromString([]byte(tt.a))
   619  		b.FromString([]byte(tt.b))
   620  		c.Assert(a.Compare(&b), Equals, tt.cmp)
   621  	}
   622  }
   623  
   624  func (s *testMyDecimalSuite) TestMaxDecimal(c *C) {
   625  	type tcase struct {
   626  		prec   int
   627  		frac   int
   628  		result string
   629  	}
   630  	tests := []tcase{
   631  		{1, 1, "0.9"},
   632  		{1, 0, "9"},
   633  		{2, 1, "9.9"},
   634  		{4, 2, "99.99"},
   635  		{6, 3, "999.999"},
   636  		{8, 4, "9999.9999"},
   637  		{10, 5, "99999.99999"},
   638  		{12, 6, "999999.999999"},
   639  		{14, 7, "9999999.9999999"},
   640  		{16, 8, "99999999.99999999"},
   641  		{18, 9, "999999999.999999999"},
   642  		{20, 10, "9999999999.9999999999"},
   643  		{20, 20, "0.99999999999999999999"},
   644  		{20, 0, "99999999999999999999"},
   645  		{40, 20, "99999999999999999999.99999999999999999999"},
   646  	}
   647  	for _, tt := range tests {
   648  		var dec MyDecimal
   649  		maxDecimal(tt.prec, tt.frac, &dec)
   650  		str := dec.ToString()
   651  		c.Assert(string(str), Equals, tt.result)
   652  	}
   653  }
   654  
   655  func (s *testMyDecimalSuite) TestNeg(c *C) {
   656  	type testCase struct {
   657  		a      string
   658  		result string
   659  		err    error
   660  	}
   661  	tests := []testCase{
   662  		{"-0.0000000000000000000000000000000000000000000000000017382578996420603", "0.0000000000000000000000000000000000000000000000000017382578996420603", nil},
   663  		{"-13890436710184412000000000000000000000000000000000000000000000000000000000000", "13890436710184412000000000000000000000000000000000000000000000000000000000000", nil},
   664  		{"0", "0", nil},
   665  	}
   666  	for _, tt := range tests {
   667  		a := NewDecFromStringForTest(tt.a)
   668  		negResult := DecimalNeg(a)
   669  		result := negResult.ToString()
   670  		c.Assert(string(result), Equals, tt.result)
   671  	}
   672  }
   673  
   674  func (s *testMyDecimalSuite) TestAdd(c *C) {
   675  	type testCase struct {
   676  		a      string
   677  		b      string
   678  		result string
   679  		err    error
   680  	}
   681  	tests := []testCase{
   682  		{".00012345000098765", "123.45", "123.45012345000098765", nil},
   683  		{".1", ".45", "0.55", nil},
   684  		{"1234500009876.5", ".00012345000098765", "1234500009876.50012345000098765", nil},
   685  		{"9999909999999.5", ".555", "9999910000000.055", nil},
   686  		{"99999999", "1", "100000000", nil},
   687  		{"989999999", "1", "990000000", nil},
   688  		{"999999999", "1", "1000000000", nil},
   689  		{"12345", "123.45", "12468.45", nil},
   690  		{"-12345", "-123.45", "-12468.45", nil},
   691  		{"-12345", "123.45", "-12221.55", nil},
   692  		{"12345", "-123.45", "12221.55", nil},
   693  		{"123.45", "-12345", "-12221.55", nil},
   694  		{"-123.45", "12345", "12221.55", nil},
   695  		{"5", "-6.0", "-1.0", nil},
   696  		{"2" + strings.Repeat("1", 71), strings.Repeat("8", 81), "8888888890" + strings.Repeat("9", 71), nil},
   697  	}
   698  	for _, tt := range tests {
   699  		a := NewDecFromStringForTest(tt.a)
   700  		b := NewDecFromStringForTest(tt.b)
   701  		var sum MyDecimal
   702  		err := DecimalAdd(a, b, &sum)
   703  		c.Assert(err, Equals, tt.err)
   704  		result := sum.ToString()
   705  		c.Assert(string(result), Equals, tt.result)
   706  	}
   707  }
   708  
   709  func (s *testMyDecimalSuite) TestSub(c *C) {
   710  	type tcase struct {
   711  		a      string
   712  		b      string
   713  		result string
   714  		err    error
   715  	}
   716  	tests := []tcase{
   717  		{".00012345000098765", "123.45", "-123.44987654999901235", nil},
   718  		{"1234500009876.5", ".00012345000098765", "1234500009876.49987654999901235", nil},
   719  		{"9999900000000.5", ".555", "9999899999999.945", nil},
   720  		{"1111.5551", "1111.555", "0.0001", nil},
   721  		{".555", ".555", "0", nil},
   722  		{"10000000", "1", "9999999", nil},
   723  		{"1000001000", ".1", "1000000999.9", nil},
   724  		{"1000000000", ".1", "999999999.9", nil},
   725  		{"12345", "123.45", "12221.55", nil},
   726  		{"-12345", "-123.45", "-12221.55", nil},
   727  		{"123.45", "12345", "-12221.55", nil},
   728  		{"-123.45", "-12345", "12221.55", nil},
   729  		{"-12345", "123.45", "-12468.45", nil},
   730  		{"12345", "-123.45", "12468.45", nil},
   731  	}
   732  	for _, tt := range tests {
   733  		var a, b, sum MyDecimal
   734  		a.FromString([]byte(tt.a))
   735  		b.FromString([]byte(tt.b))
   736  		err := DecimalSub(&a, &b, &sum)
   737  		c.Assert(err, Equals, tt.err)
   738  		result := sum.ToString()
   739  		c.Assert(string(result), Equals, tt.result)
   740  	}
   741  }
   742  
   743  func (s *testMyDecimalSuite) TestMul(c *C) {
   744  	type tcase struct {
   745  		a      string
   746  		b      string
   747  		result string
   748  		err    error
   749  	}
   750  	tests := []tcase{
   751  		{"12", "10", "120", nil},
   752  		{"-123.456", "98765.4321", "-12193185.1853376", nil},
   753  		{"-123456000000", "98765432100000", "-12193185185337600000000000", nil},
   754  		{"123456", "987654321", "121931851853376", nil},
   755  		{"123456", "9876543210", "1219318518533760", nil},
   756  		{"123", "0.01", "1.23", nil},
   757  		{"123", "0", "0", nil},
   758  		{"-0.0000000000000000000000000000000000000000000000000017382578996420603", "-13890436710184412000000000000000000000000000000000000000000000000000000000000", "0.000000000000000000000000000000", ErrTruncated},
   759  		{"1" + strings.Repeat("0", 60), "1" + strings.Repeat("0", 60), "0", ErrOverflow},
   760  		{"0.5999991229316", "0.918755041726043", "0.5512522192246113614062276588", nil},
   761  		{"0.5999991229317", "0.918755041726042", "0.5512522192247026369112773314", nil},
   762  	}
   763  	for _, tt := range tests {
   764  		var a, b, product MyDecimal
   765  		a.FromString([]byte(tt.a))
   766  		b.FromString([]byte(tt.b))
   767  		err := DecimalMul(&a, &b, &product)
   768  		c.Check(err, Equals, tt.err)
   769  		result := product.String()
   770  		c.Assert(result, Equals, tt.result)
   771  	}
   772  }
   773  
   774  func (s *testMyDecimalSuite) TestDivMod(c *C) {
   775  	type tcase struct {
   776  		a      string
   777  		b      string
   778  		result string
   779  		err    error
   780  	}
   781  	tests := []tcase{
   782  		{"120", "10", "12.000000000", nil},
   783  		{"123", "0.01", "12300.000000000", nil},
   784  		{"120", "100000000000.00000", "0.000000001200000000", nil},
   785  		{"123", "0", "", ErrDivByZero},
   786  		{"0", "0", "", ErrDivByZero},
   787  		{"-12193185.1853376", "98765.4321", "-123.456000000000000000", nil},
   788  		{"121931851853376", "987654321", "123456.000000000", nil},
   789  		{"0", "987", "0", nil},
   790  		{"1", "3", "0.333333333", nil},
   791  		{"1.000000000000", "3", "0.333333333333333333", nil},
   792  		{"1", "1", "1.000000000", nil},
   793  		{"0.0123456789012345678912345", "9999999999", "0.000000000001234567890246913578148141", nil},
   794  		{"10.333000000", "12.34500", "0.837019036046982584042122316", nil},
   795  		{"10.000000000060", "2", "5.000000000030000000", nil},
   796  		{"51", "0.003430", "14868.804664723032069970", nil},
   797  	}
   798  	for _, tt := range tests {
   799  		var a, b, to MyDecimal
   800  		a.FromString([]byte(tt.a))
   801  		b.FromString([]byte(tt.b))
   802  		err := doDivMod(&a, &b, &to, nil, 5)
   803  		c.Check(err, Equals, tt.err)
   804  		if tt.err == ErrDivByZero {
   805  			continue
   806  		}
   807  		result := to.ToString()
   808  		c.Assert(string(result), Equals, tt.result)
   809  	}
   810  
   811  	tests = []tcase{
   812  		{"234", "10", "4", nil},
   813  		{"234.567", "10.555", "2.357", nil},
   814  		{"-234.567", "10.555", "-2.357", nil},
   815  		{"234.567", "-10.555", "2.357", nil},
   816  		{"99999999999999999999999999999999999999", "3", "0", nil},
   817  		{"51", "0.003430", "0.002760", nil},
   818  		{"0.0000000001", "1.0", "0.0000000001", nil},
   819  	}
   820  	for _, tt := range tests {
   821  		var a, b, to MyDecimal
   822  		a.FromString([]byte(tt.a))
   823  		b.FromString([]byte(tt.b))
   824  		ec := doDivMod(&a, &b, nil, &to, 0)
   825  		c.Check(ec, Equals, tt.err)
   826  		if tt.err == ErrDivByZero {
   827  			continue
   828  		}
   829  		result := to.ToString()
   830  		c.Assert(string(result), Equals, tt.result)
   831  	}
   832  
   833  	tests = []tcase{
   834  		{"1", "1", "1.0000", nil},
   835  		{"1.00", "1", "1.000000", nil},
   836  		{"1", "1.000", "1.0000", nil},
   837  		{"2", "3", "0.6667", nil},
   838  		{"51", "0.003430", "14868.8047", nil},
   839  	}
   840  	for _, tt := range tests {
   841  		var a, b, to MyDecimal
   842  		a.FromString([]byte(tt.a))
   843  		b.FromString([]byte(tt.b))
   844  		ec := DecimalDiv(&a, &b, &to, DivFracIncr)
   845  		c.Check(ec, Equals, tt.err)
   846  		if tt.err == ErrDivByZero {
   847  			continue
   848  		}
   849  		c.Assert(to.String(), Equals, tt.result)
   850  	}
   851  
   852  	tests = []tcase{
   853  		{"1", "2.0", "1.0", nil},
   854  		{"1.0", "2", "1.0", nil},
   855  		{"2.23", "3", "2.23", nil},
   856  		{"51", "0.003430", "0.002760", nil},
   857  	}
   858  	for _, tt := range tests {
   859  		var a, b, to MyDecimal
   860  		a.FromString([]byte(tt.a))
   861  		b.FromString([]byte(tt.b))
   862  		ec := DecimalMod(&a, &b, &to)
   863  		c.Check(ec, Equals, tt.err)
   864  		if tt.err == ErrDivByZero {
   865  			continue
   866  		}
   867  		c.Assert(to.String(), Equals, tt.result)
   868  	}
   869  }
   870  
   871  func (s *testMyDecimalSuite) TestMaxOrMin(c *C) {
   872  	type tcase struct {
   873  		neg    bool
   874  		prec   int
   875  		frac   int
   876  		result string
   877  	}
   878  	tests := []tcase{
   879  		{true, 2, 1, "-9.9"},
   880  		{false, 1, 1, "0.9"},
   881  		{true, 1, 0, "-9"},
   882  		{false, 0, 0, "0"},
   883  		{false, 4, 2, "99.99"},
   884  	}
   885  	for _, tt := range tests {
   886  		dec := NewMaxOrMinDec(tt.neg, tt.prec, tt.frac)
   887  		c.Assert(dec.String(), Equals, tt.result)
   888  	}
   889  }
   890  
   891  func benchmarkMyDecimalToBinOrHashCases() []string {
   892  	return []string{
   893  		"1.000000000000", "3", "12.000000000", "120",
   894  		"120000", "100000000000.00000", "0.000000001200000000",
   895  		"98765.4321", "-123.456000000000000000",
   896  		"0", "0000000000", "0.00000000000",
   897  	}
   898  }
   899  
   900  func BenchmarkMyDecimalToBin(b *testing.B) {
   901  	cases := benchmarkMyDecimalToBinOrHashCases()
   902  	decs := make([]*MyDecimal, 0, len(cases))
   903  	for _, ca := range cases {
   904  		var dec MyDecimal
   905  		if err := dec.FromString([]byte(ca)); err != nil {
   906  			b.Fatal(err)
   907  		}
   908  		decs = append(decs, &dec)
   909  	}
   910  
   911  	b.ResetTimer()
   912  	for i := 0; i < b.N; i++ {
   913  		for _, dec := range decs {
   914  			prec, frac := dec.PrecisionAndFrac()
   915  			_, err := dec.ToBin(prec, frac)
   916  			if err != nil {
   917  				b.Fatal(err)
   918  			}
   919  		}
   920  	}
   921  }
   922  
   923  func BenchmarkMyDecimalToHashKey(b *testing.B) {
   924  	cases := benchmarkMyDecimalToBinOrHashCases()
   925  	decs := make([]*MyDecimal, 0, len(cases))
   926  	for _, ca := range cases {
   927  		var dec MyDecimal
   928  		if err := dec.FromString([]byte(ca)); err != nil {
   929  			b.Fatal(err)
   930  		}
   931  		decs = append(decs, &dec)
   932  	}
   933  
   934  	b.ResetTimer()
   935  	for i := 0; i < b.N; i++ {
   936  		for _, dec := range decs {
   937  			_, err := dec.ToHashKey()
   938  			if err != nil {
   939  				b.Fatal(err)
   940  			}
   941  		}
   942  	}
   943  }