github.com/XiaoMi/Gaea@v1.2.5/parser/tidb-types/mydecimal.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  	"math"
    18  	"strconv"
    19  
    20  	"github.com/pingcap/errors"
    21  
    22  	"github.com/XiaoMi/Gaea/mysql"
    23  	"github.com/XiaoMi/Gaea/parser/terror"
    24  )
    25  
    26  // RoundMode is the type for round mode.
    27  type RoundMode string
    28  
    29  // constant values.
    30  const (
    31  	ten0 = 1
    32  	ten1 = 10
    33  	ten2 = 100
    34  	ten3 = 1000
    35  	ten4 = 10000
    36  	ten5 = 100000
    37  	ten6 = 1000000
    38  	ten7 = 10000000
    39  	ten8 = 100000000
    40  	ten9 = 1000000000
    41  
    42  	maxWordBufLen = 9 // A MyDecimal holds 9 words.
    43  	digitsPerWord = 9 // A word holds 9 digits.
    44  	wordSize      = 4 // A word is 4 bytes int32.
    45  	digMask       = ten8
    46  	wordBase      = ten9
    47  	wordMax       = wordBase - 1
    48  	notFixedDec   = 31
    49  
    50  	DivFracIncr = 4
    51  
    52  	// ModeHalfEven rounds normally.
    53  	ModeHalfEven RoundMode = "ModeHalfEven"
    54  	// Truncate just truncates the decimal.
    55  	ModeTruncate RoundMode = "Truncate"
    56  	// Ceiling is not supported now.
    57  	modeCeiling RoundMode = "Ceiling"
    58  )
    59  
    60  var (
    61  	wordBufLen = 9
    62  	powers10   = [10]int32{ten0, ten1, ten2, ten3, ten4, ten5, ten6, ten7, ten8, ten9}
    63  	dig2bytes  = [10]int{0, 1, 1, 2, 2, 3, 3, 4, 4, 4}
    64  	fracMax    = [8]int32{
    65  		900000000,
    66  		990000000,
    67  		999000000,
    68  		999900000,
    69  		999990000,
    70  		999999000,
    71  		999999900,
    72  		999999990,
    73  	}
    74  	zeroMyDecimal = MyDecimal{}
    75  )
    76  
    77  // add adds a and b and carry, returns the sum and new carry.
    78  func add(a, b, carry int32) (int32, int32) {
    79  	sum := a + b + carry
    80  	if sum >= wordBase {
    81  		carry = 1
    82  		sum -= wordBase
    83  	} else {
    84  		carry = 0
    85  	}
    86  	return sum, carry
    87  }
    88  
    89  // add2 adds a and b and carry, returns the sum and new carry.
    90  // It is only used in DecimalMul.
    91  func add2(a, b, carry int32) (int32, int32) {
    92  	sum := int64(a) + int64(b) + int64(carry)
    93  	if sum >= wordBase {
    94  		carry = 1
    95  		sum -= wordBase
    96  	} else {
    97  		carry = 0
    98  	}
    99  
   100  	if sum >= wordBase {
   101  		sum -= wordBase
   102  		carry++
   103  	}
   104  	return int32(sum), carry
   105  }
   106  
   107  // sub subtracts b and carry from a, returns the diff and new carry.
   108  func sub(a, b, carry int32) (int32, int32) {
   109  	diff := a - b - carry
   110  	if diff < 0 {
   111  		carry = 1
   112  		diff += wordBase
   113  	} else {
   114  		carry = 0
   115  	}
   116  	return diff, carry
   117  }
   118  
   119  // sub2 subtracts b and carry from a, returns the diff and new carry.
   120  // the new carry may be 2.
   121  func sub2(a, b, carry int32) (int32, int32) {
   122  	diff := a - b - carry
   123  	if diff < 0 {
   124  		carry = 1
   125  		diff += wordBase
   126  	} else {
   127  		carry = 0
   128  	}
   129  	if diff < 0 {
   130  		diff += wordBase
   131  		carry++
   132  	}
   133  	return diff, carry
   134  }
   135  
   136  // fixWordCntError limits word count in wordBufLen, and returns overflow or truncate error.
   137  func fixWordCntError(wordsInt, wordsFrac int) (newWordsInt int, newWordsFrac int, err error) {
   138  	if wordsInt+wordsFrac > wordBufLen {
   139  		if wordsInt > wordBufLen {
   140  			return wordBufLen, 0, ErrOverflow
   141  		}
   142  		return wordsInt, wordBufLen - wordsInt, ErrTruncated
   143  	}
   144  	return wordsInt, wordsFrac, nil
   145  }
   146  
   147  /*
   148    countLeadingZeroes returns the number of leading zeroes that can be removed from fraction.
   149  
   150    @param   i    start index
   151    @param   word value to compare against list of powers of 10
   152  */
   153  func countLeadingZeroes(i int, word int32) int {
   154  	leading := 0
   155  	for word < powers10[i] {
   156  		i--
   157  		leading++
   158  	}
   159  	return leading
   160  }
   161  
   162  /*
   163    countTrailingZeros returns the number of trailing zeroes that can be removed from fraction.
   164  
   165    @param   i    start index
   166    @param   word  value to compare against list of powers of 10
   167  */
   168  func countTrailingZeroes(i int, word int32) int {
   169  	trailing := 0
   170  	for word%powers10[i] == 0 {
   171  		i++
   172  		trailing++
   173  	}
   174  	return trailing
   175  }
   176  
   177  func digitsToWords(digits int) int {
   178  	return (digits + digitsPerWord - 1) / digitsPerWord
   179  }
   180  
   181  // MyDecimalStructSize is the struct size of MyDecimal.
   182  const MyDecimalStructSize = 40
   183  
   184  // MyDecimal represents a decimal value.
   185  type MyDecimal struct {
   186  	digitsInt int8 // the number of *decimal* digits before the point.
   187  
   188  	digitsFrac int8 // the number of decimal digits after the point.
   189  
   190  	resultFrac int8 // result fraction digits.
   191  
   192  	negative bool
   193  
   194  	//  wordBuf is an array of int32 words.
   195  	// A word is an int32 value can hold 9 digits.(0 <= word < wordBase)
   196  	wordBuf [maxWordBufLen]int32
   197  }
   198  
   199  // IsNegative returns whether a decimal is negative.
   200  func (d *MyDecimal) IsNegative() bool {
   201  	return d.negative
   202  }
   203  
   204  // GetDigitsFrac returns the digitsFrac.
   205  func (d *MyDecimal) GetDigitsFrac() int8 {
   206  	return d.digitsFrac
   207  }
   208  
   209  // String returns the decimal string representation rounded to resultFrac.
   210  func (d *MyDecimal) String() string {
   211  	tmp := *d
   212  	err := tmp.Round(&tmp, int(tmp.resultFrac), ModeHalfEven)
   213  	terror.Log(errors.Trace(err))
   214  	return string(tmp.ToString())
   215  }
   216  
   217  func (d *MyDecimal) stringSize() int {
   218  	// sign, zero integer and dot.
   219  	return int(d.digitsInt + d.digitsFrac + 3)
   220  }
   221  
   222  func (d *MyDecimal) removeLeadingZeros() (wordIdx int, digitsInt int) {
   223  	digitsInt = int(d.digitsInt)
   224  	i := ((digitsInt - 1) % digitsPerWord) + 1
   225  	for digitsInt > 0 && d.wordBuf[wordIdx] == 0 {
   226  		digitsInt -= i
   227  		i = digitsPerWord
   228  		wordIdx++
   229  	}
   230  	if digitsInt > 0 {
   231  		digitsInt -= countLeadingZeroes((digitsInt-1)%digitsPerWord, d.wordBuf[wordIdx])
   232  	} else {
   233  		digitsInt = 0
   234  	}
   235  	return
   236  }
   237  
   238  func (d *MyDecimal) removeTrailingZeros() (lastWordIdx int, digitsFrac int) {
   239  	digitsFrac = int(d.digitsFrac)
   240  	i := ((digitsFrac - 1) % digitsPerWord) + 1
   241  	lastWordIdx = digitsToWords(int(d.digitsInt)) + digitsToWords(int(d.digitsFrac))
   242  	for digitsFrac > 0 && d.wordBuf[lastWordIdx-1] == 0 {
   243  		digitsFrac -= i
   244  		i = digitsPerWord
   245  		lastWordIdx--
   246  	}
   247  	if digitsFrac > 0 {
   248  		digitsFrac -= countTrailingZeroes(9-((digitsFrac-1)%digitsPerWord), d.wordBuf[lastWordIdx-1])
   249  	} else {
   250  		digitsFrac = 0
   251  	}
   252  	return
   253  }
   254  
   255  // ToString converts decimal to its printable string representation without rounding.
   256  //
   257  //  RETURN VALUE
   258  //
   259  //      str       - result string
   260  //      errCode   - eDecOK/eDecTruncate/eDecOverflow
   261  //
   262  func (d *MyDecimal) ToString() (str []byte) {
   263  	str = make([]byte, d.stringSize())
   264  	digitsFrac := int(d.digitsFrac)
   265  	wordStartIdx, digitsInt := d.removeLeadingZeros()
   266  	if digitsInt+digitsFrac == 0 {
   267  		digitsInt = 1
   268  		wordStartIdx = 0
   269  	}
   270  
   271  	digitsIntLen := digitsInt
   272  	if digitsIntLen == 0 {
   273  		digitsIntLen = 1
   274  	}
   275  	digitsFracLen := digitsFrac
   276  	length := digitsIntLen + digitsFracLen
   277  	if d.negative {
   278  		length++
   279  	}
   280  	if digitsFrac > 0 {
   281  		length++
   282  	}
   283  	str = str[:length]
   284  	strIdx := 0
   285  	if d.negative {
   286  		str[strIdx] = '-'
   287  		strIdx++
   288  	}
   289  	var fill int
   290  	if digitsFrac > 0 {
   291  		fracIdx := strIdx + digitsIntLen
   292  		fill = digitsFracLen - digitsFrac
   293  		wordIdx := wordStartIdx + digitsToWords(digitsInt)
   294  		str[fracIdx] = '.'
   295  		fracIdx++
   296  		for ; digitsFrac > 0; digitsFrac -= digitsPerWord {
   297  			x := d.wordBuf[wordIdx]
   298  			wordIdx++
   299  			for i := myMin(digitsFrac, digitsPerWord); i > 0; i-- {
   300  				y := x / digMask
   301  				str[fracIdx] = byte(y) + '0'
   302  				fracIdx++
   303  				x -= y * digMask
   304  				x *= 10
   305  			}
   306  		}
   307  		for ; fill > 0; fill-- {
   308  			str[fracIdx] = '0'
   309  			fracIdx++
   310  		}
   311  	}
   312  	fill = digitsIntLen - digitsInt
   313  	if digitsInt == 0 {
   314  		fill-- /* symbol 0 before digital point */
   315  	}
   316  	for ; fill > 0; fill-- {
   317  		str[strIdx] = '0'
   318  		strIdx++
   319  	}
   320  	if digitsInt > 0 {
   321  		strIdx += digitsInt
   322  		wordIdx := wordStartIdx + digitsToWords(digitsInt)
   323  		for ; digitsInt > 0; digitsInt -= digitsPerWord {
   324  			wordIdx--
   325  			x := d.wordBuf[wordIdx]
   326  			for i := myMin(digitsInt, digitsPerWord); i > 0; i-- {
   327  				y := x / 10
   328  				strIdx--
   329  				str[strIdx] = '0' + byte(x-y*10)
   330  				x = y
   331  			}
   332  		}
   333  	} else {
   334  		str[strIdx] = '0'
   335  	}
   336  	return
   337  }
   338  
   339  // FromString parses decimal from string.
   340  func (d *MyDecimal) FromString(str []byte) error {
   341  	for i := 0; i < len(str); i++ {
   342  		if !isSpace(str[i]) {
   343  			str = str[i:]
   344  			break
   345  		}
   346  	}
   347  	if len(str) == 0 {
   348  		*d = zeroMyDecimal
   349  		return ErrBadNumber
   350  	}
   351  	switch str[0] {
   352  	case '-':
   353  		d.negative = true
   354  		fallthrough
   355  	case '+':
   356  		str = str[1:]
   357  	}
   358  	var strIdx int
   359  	for strIdx < len(str) && isDigit(str[strIdx]) {
   360  		strIdx++
   361  	}
   362  	digitsInt := strIdx
   363  	var digitsFrac int
   364  	var endIdx int
   365  	if strIdx < len(str) && str[strIdx] == '.' {
   366  		endIdx = strIdx + 1
   367  		for endIdx < len(str) && isDigit(str[endIdx]) {
   368  			endIdx++
   369  		}
   370  		digitsFrac = endIdx - strIdx - 1
   371  	} else {
   372  		digitsFrac = 0
   373  		endIdx = strIdx
   374  	}
   375  	if digitsInt+digitsFrac == 0 {
   376  		*d = zeroMyDecimal
   377  		return ErrBadNumber
   378  	}
   379  	wordsInt := digitsToWords(digitsInt)
   380  	wordsFrac := digitsToWords(digitsFrac)
   381  	wordsInt, wordsFrac, err := fixWordCntError(wordsInt, wordsFrac)
   382  	if err != nil {
   383  		digitsFrac = wordsFrac * digitsPerWord
   384  		if err == ErrOverflow {
   385  			digitsInt = wordsInt * digitsPerWord
   386  		}
   387  	}
   388  	d.digitsInt = int8(digitsInt)
   389  	d.digitsFrac = int8(digitsFrac)
   390  	wordIdx := wordsInt
   391  	strIdxTmp := strIdx
   392  	var word int32
   393  	var innerIdx int
   394  	for digitsInt > 0 {
   395  		digitsInt--
   396  		strIdx--
   397  		word += int32(str[strIdx]-'0') * powers10[innerIdx]
   398  		innerIdx++
   399  		if innerIdx == digitsPerWord {
   400  			wordIdx--
   401  			d.wordBuf[wordIdx] = word
   402  			word = 0
   403  			innerIdx = 0
   404  		}
   405  	}
   406  	if innerIdx != 0 {
   407  		wordIdx--
   408  		d.wordBuf[wordIdx] = word
   409  	}
   410  
   411  	wordIdx = wordsInt
   412  	strIdx = strIdxTmp
   413  	word = 0
   414  	innerIdx = 0
   415  	for digitsFrac > 0 {
   416  		digitsFrac--
   417  		strIdx++
   418  		word = int32(str[strIdx]-'0') + word*10
   419  		innerIdx++
   420  		if innerIdx == digitsPerWord {
   421  			d.wordBuf[wordIdx] = word
   422  			wordIdx++
   423  			word = 0
   424  			innerIdx = 0
   425  		}
   426  	}
   427  	if innerIdx != 0 {
   428  		d.wordBuf[wordIdx] = word * powers10[digitsPerWord-innerIdx]
   429  	}
   430  	if endIdx+1 <= len(str) && (str[endIdx] == 'e' || str[endIdx] == 'E') {
   431  		exponent, err1 := strToInt(string(str[endIdx+1:]))
   432  		if err1 != nil {
   433  			err = errors.Cause(err1)
   434  			if err != ErrTruncated {
   435  				*d = zeroMyDecimal
   436  			}
   437  		}
   438  		if exponent > math.MaxInt32/2 {
   439  			negative := d.negative
   440  			maxDecimal(wordBufLen*digitsPerWord, 0, d)
   441  			d.negative = negative
   442  			err = ErrOverflow
   443  		}
   444  		if exponent < math.MinInt32/2 && err != ErrOverflow {
   445  			*d = zeroMyDecimal
   446  			err = ErrTruncated
   447  		}
   448  		if err != ErrOverflow {
   449  			shiftErr := d.Shift(int(exponent))
   450  			if shiftErr != nil {
   451  				if shiftErr == ErrOverflow {
   452  					negative := d.negative
   453  					maxDecimal(wordBufLen*digitsPerWord, 0, d)
   454  					d.negative = negative
   455  				}
   456  				err = shiftErr
   457  			}
   458  		}
   459  	}
   460  	allZero := true
   461  	for i := 0; i < wordBufLen; i++ {
   462  		if d.wordBuf[i] != 0 {
   463  			allZero = false
   464  			break
   465  		}
   466  	}
   467  	if allZero {
   468  		d.negative = false
   469  	}
   470  	d.resultFrac = d.digitsFrac
   471  	return err
   472  }
   473  
   474  // Shift shifts decimal digits in given number (with rounding if it need), shift > 0 means shift to left shift,
   475  // shift < 0 means right shift. In fact it is multiplying on 10^shift.
   476  //
   477  // RETURN
   478  //   eDecOK          OK
   479  //   eDecOverflow    operation lead to overflow, number is untoched
   480  //   eDecTruncated   number was rounded to fit into buffer
   481  //
   482  func (d *MyDecimal) Shift(shift int) error {
   483  	var err error
   484  	if shift == 0 {
   485  		return nil
   486  	}
   487  	var (
   488  		// digitBegin is index of first non zero digit (all indexes from 0).
   489  		digitBegin int
   490  		// digitEnd is index of position after last decimal digit.
   491  		digitEnd int
   492  		// point is index of digit position just after point.
   493  		point = digitsToWords(int(d.digitsInt)) * digitsPerWord
   494  		// new point position.
   495  		newPoint = point + shift
   496  		// number of digits in result.
   497  		digitsInt, digitsFrac int
   498  		newFront              int
   499  	)
   500  	digitBegin, digitEnd = d.digitBounds()
   501  	if digitBegin == digitEnd {
   502  		*d = zeroMyDecimal
   503  		return nil
   504  	}
   505  
   506  	digitsInt = newPoint - digitBegin
   507  	if digitsInt < 0 {
   508  		digitsInt = 0
   509  	}
   510  	digitsFrac = digitEnd - newPoint
   511  	if digitsFrac < 0 {
   512  		digitsFrac = 0
   513  	}
   514  	wordsInt := digitsToWords(digitsInt)
   515  	wordsFrac := digitsToWords(digitsFrac)
   516  	newLen := wordsInt + wordsFrac
   517  	if newLen > wordBufLen {
   518  		lack := newLen - wordBufLen
   519  		if wordsFrac < lack {
   520  			return ErrOverflow
   521  		}
   522  		/* cut off fraction part to allow new number to fit in our buffer */
   523  		err = ErrTruncated
   524  		wordsFrac -= lack
   525  		diff := digitsFrac - wordsFrac*digitsPerWord
   526  		err1 := d.Round(d, digitEnd-point-diff, ModeHalfEven)
   527  		if err1 != nil {
   528  			return errors.Trace(err1)
   529  		}
   530  		digitEnd -= diff
   531  		digitsFrac = wordsFrac * digitsPerWord
   532  		if digitEnd <= digitBegin {
   533  			/*
   534  			   We lost all digits (they will be shifted out of buffer), so we can
   535  			   just return 0.
   536  			*/
   537  			*d = zeroMyDecimal
   538  			return ErrTruncated
   539  		}
   540  	}
   541  
   542  	if shift%digitsPerWord != 0 {
   543  		var lMiniShift, rMiniShift, miniShift int
   544  		var doLeft bool
   545  		/*
   546  		   Calculate left/right shift to align decimal digits inside our bug
   547  		   digits correctly.
   548  		*/
   549  		if shift > 0 {
   550  			lMiniShift = shift % digitsPerWord
   551  			rMiniShift = digitsPerWord - lMiniShift
   552  			doLeft = lMiniShift <= digitBegin
   553  		} else {
   554  			rMiniShift = (-shift) % digitsPerWord
   555  			lMiniShift = digitsPerWord - rMiniShift
   556  			doLeft = (digitsPerWord*wordBufLen - digitEnd) < rMiniShift
   557  		}
   558  		if doLeft {
   559  			d.doMiniLeftShift(lMiniShift, digitBegin, digitEnd)
   560  			miniShift = -lMiniShift
   561  		} else {
   562  			d.doMiniRightShift(rMiniShift, digitBegin, digitEnd)
   563  			miniShift = rMiniShift
   564  		}
   565  		newPoint += miniShift
   566  		/*
   567  		   If number is shifted and correctly aligned in buffer we can finish.
   568  		*/
   569  		if shift+miniShift == 0 && (newPoint-digitsInt) < digitsPerWord {
   570  			d.digitsInt = int8(digitsInt)
   571  			d.digitsFrac = int8(digitsFrac)
   572  			return err /* already shifted as it should be */
   573  		}
   574  		digitBegin += miniShift
   575  		digitEnd += miniShift
   576  	}
   577  
   578  	/* if new 'decimal front' is in first digit, we do not need move digits */
   579  	newFront = newPoint - digitsInt
   580  	if newFront >= digitsPerWord || newFront < 0 {
   581  		/* need to move digits */
   582  		var wordShift int
   583  		if newFront > 0 {
   584  			/* move left */
   585  			wordShift = newFront / digitsPerWord
   586  			to := digitBegin/digitsPerWord - wordShift
   587  			barier := (digitEnd-1)/digitsPerWord - wordShift
   588  			for ; to <= barier; to++ {
   589  				d.wordBuf[to] = d.wordBuf[to+wordShift]
   590  			}
   591  			for barier += wordShift; to <= barier; to++ {
   592  				d.wordBuf[to] = 0
   593  			}
   594  			wordShift = -wordShift
   595  		} else {
   596  			/* move right */
   597  			wordShift = (1 - newFront) / digitsPerWord
   598  			to := (digitEnd-1)/digitsPerWord + wordShift
   599  			barier := digitBegin/digitsPerWord + wordShift
   600  			for ; to >= barier; to-- {
   601  				d.wordBuf[to] = d.wordBuf[to-wordShift]
   602  			}
   603  			for barier -= wordShift; to >= barier; to-- {
   604  				d.wordBuf[to] = 0
   605  			}
   606  		}
   607  		digitShift := wordShift * digitsPerWord
   608  		digitBegin += digitShift
   609  		digitEnd += digitShift
   610  		newPoint += digitShift
   611  	}
   612  	/*
   613  	   If there are gaps then fill them with 0.
   614  
   615  	   Only one of following 'for' loops will work because wordIdxBegin <= wordIdxEnd.
   616  	*/
   617  	wordIdxBegin := digitBegin / digitsPerWord
   618  	wordIdxEnd := (digitEnd - 1) / digitsPerWord
   619  	wordIdxNewPoint := 0
   620  
   621  	/* We don't want negative new_point below */
   622  	if newPoint != 0 {
   623  		wordIdxNewPoint = (newPoint - 1) / digitsPerWord
   624  	}
   625  	if wordIdxNewPoint > wordIdxEnd {
   626  		for wordIdxNewPoint > wordIdxEnd {
   627  			d.wordBuf[wordIdxNewPoint] = 0
   628  			wordIdxNewPoint--
   629  		}
   630  	} else {
   631  		for ; wordIdxNewPoint < wordIdxBegin; wordIdxNewPoint++ {
   632  			d.wordBuf[wordIdxNewPoint] = 0
   633  		}
   634  	}
   635  	d.digitsInt = int8(digitsInt)
   636  	d.digitsFrac = int8(digitsFrac)
   637  	return err
   638  }
   639  
   640  /*
   641    digitBounds returns bounds of decimal digits in the number.
   642  
   643        start - index (from 0 ) of first decimal digits.
   644        end   - index of position just after last decimal digit.
   645  */
   646  func (d *MyDecimal) digitBounds() (start, end int) {
   647  	var i int
   648  	bufBeg := 0
   649  	bufLen := digitsToWords(int(d.digitsInt)) + digitsToWords(int(d.digitsFrac))
   650  	bufEnd := bufLen - 1
   651  
   652  	/* find non-zero digit from number beginning */
   653  	for bufBeg < bufLen && d.wordBuf[bufBeg] == 0 {
   654  		bufBeg++
   655  	}
   656  	if bufBeg >= bufLen {
   657  		return 0, 0
   658  	}
   659  
   660  	/* find non-zero decimal digit from number beginning */
   661  	if bufBeg == 0 && d.digitsInt > 0 {
   662  		i = (int(d.digitsInt) - 1) % digitsPerWord
   663  		start = digitsPerWord - i - 1
   664  	} else {
   665  		i = digitsPerWord - 1
   666  		start = bufBeg * digitsPerWord
   667  	}
   668  	if bufBeg < bufLen {
   669  		start += countLeadingZeroes(i, d.wordBuf[bufBeg])
   670  	}
   671  
   672  	/* find non-zero digit at the end */
   673  	for bufEnd > bufBeg && d.wordBuf[bufEnd] == 0 {
   674  		bufEnd--
   675  	}
   676  	/* find non-zero decimal digit from the end */
   677  	if bufEnd == bufLen-1 && d.digitsFrac > 0 {
   678  		i = (int(d.digitsFrac)-1)%digitsPerWord + 1
   679  		end = bufEnd*digitsPerWord + i
   680  		i = digitsPerWord - i + 1
   681  	} else {
   682  		end = (bufEnd + 1) * digitsPerWord
   683  		i = 1
   684  	}
   685  	end -= countTrailingZeroes(i, d.wordBuf[bufEnd])
   686  	return start, end
   687  }
   688  
   689  /*
   690    doMiniLeftShift does left shift for alignment of data in buffer.
   691  
   692      shift   number of decimal digits on which it should be shifted
   693      beg/end bounds of decimal digits (see digitsBounds())
   694  
   695    NOTE
   696      Result fitting in the buffer should be garanted.
   697      'shift' have to be from 1 to digitsPerWord-1 (inclusive)
   698  */
   699  func (d *MyDecimal) doMiniLeftShift(shift, beg, end int) {
   700  	bufFrom := beg / digitsPerWord
   701  	bufEnd := (end - 1) / digitsPerWord
   702  	cShift := digitsPerWord - shift
   703  	if beg%digitsPerWord < shift {
   704  		d.wordBuf[bufFrom-1] = d.wordBuf[bufFrom] / powers10[cShift]
   705  	}
   706  	for bufFrom < bufEnd {
   707  		d.wordBuf[bufFrom] = (d.wordBuf[bufFrom]%powers10[cShift])*powers10[shift] + d.wordBuf[bufFrom+1]/powers10[cShift]
   708  		bufFrom++
   709  	}
   710  	d.wordBuf[bufFrom] = (d.wordBuf[bufFrom] % powers10[cShift]) * powers10[shift]
   711  }
   712  
   713  /*
   714    doMiniRightShift does right shift for alignment of data in buffer.
   715  
   716      shift   number of decimal digits on which it should be shifted
   717      beg/end bounds of decimal digits (see digitsBounds())
   718  
   719    NOTE
   720      Result fitting in the buffer should be garanted.
   721      'shift' have to be from 1 to digitsPerWord-1 (inclusive)
   722  */
   723  func (d *MyDecimal) doMiniRightShift(shift, beg, end int) {
   724  	bufFrom := (end - 1) / digitsPerWord
   725  	bufEnd := beg / digitsPerWord
   726  	cShift := digitsPerWord - shift
   727  	if digitsPerWord-((end-1)%digitsPerWord+1) < shift {
   728  		d.wordBuf[bufFrom+1] = (d.wordBuf[bufFrom] % powers10[shift]) * powers10[cShift]
   729  	}
   730  	for bufFrom > bufEnd {
   731  		d.wordBuf[bufFrom] = d.wordBuf[bufFrom]/powers10[shift] + (d.wordBuf[bufFrom-1]%powers10[shift])*powers10[cShift]
   732  		bufFrom--
   733  	}
   734  	d.wordBuf[bufFrom] = d.wordBuf[bufFrom] / powers10[shift]
   735  }
   736  
   737  // Round rounds the decimal to "frac" digits.
   738  //
   739  //    to			- result buffer. d == to is allowed
   740  //    frac			- to what position after fraction point to round. can be negative!
   741  //    roundMode		- round to nearest even or truncate
   742  // 			ModeHalfEven rounds normally.
   743  // 			Truncate just truncates the decimal.
   744  //
   745  // NOTES
   746  //  scale can be negative !
   747  //  one TRUNCATED error (line XXX below) isn't treated very logical :(
   748  //
   749  // RETURN VALUE
   750  //  eDecOK/eDecTruncated
   751  func (d *MyDecimal) Round(to *MyDecimal, frac int, roundMode RoundMode) (err error) {
   752  	// wordsFracTo is the number of fraction words in buffer.
   753  	wordsFracTo := (frac + 1) / digitsPerWord
   754  	if frac > 0 {
   755  		wordsFracTo = digitsToWords(frac)
   756  	}
   757  	wordsFrac := digitsToWords(int(d.digitsFrac))
   758  	wordsInt := digitsToWords(int(d.digitsInt))
   759  
   760  	var roundDigit int32
   761  	/* TODO - fix this code as it won't work for CEILING mode */
   762  	switch roundMode {
   763  	case modeCeiling:
   764  		roundDigit = 0
   765  	case ModeHalfEven:
   766  		roundDigit = 5
   767  	case ModeTruncate:
   768  		roundDigit = 10
   769  	}
   770  
   771  	if wordsInt+wordsFracTo > wordBufLen {
   772  		wordsFracTo = wordBufLen - wordsInt
   773  		frac = wordsFracTo * digitsPerWord
   774  		err = ErrTruncated
   775  	}
   776  	if int(d.digitsInt)+frac < 0 {
   777  		*to = zeroMyDecimal
   778  		return nil
   779  	}
   780  	if to != d {
   781  		copy(to.wordBuf[:], d.wordBuf[:])
   782  		to.negative = d.negative
   783  		to.digitsInt = int8(myMin(wordsInt, wordBufLen) * digitsPerWord)
   784  	}
   785  	if wordsFracTo > wordsFrac {
   786  		idx := wordsInt + wordsFrac
   787  		for wordsFracTo > wordsFrac {
   788  			wordsFracTo--
   789  			to.wordBuf[idx] = 0
   790  			idx++
   791  		}
   792  		to.digitsFrac = int8(frac)
   793  		to.resultFrac = to.digitsFrac
   794  		return
   795  	}
   796  	if frac >= int(d.digitsFrac) {
   797  		to.digitsFrac = int8(frac)
   798  		to.resultFrac = to.digitsFrac
   799  		return
   800  	}
   801  
   802  	// Do increment.
   803  	toIdx := wordsInt + wordsFracTo - 1
   804  	if frac == wordsFracTo*digitsPerWord {
   805  		doInc := false
   806  		switch roundDigit {
   807  		// Notice: No support for ceiling mode now.
   808  		case 0:
   809  			// If any word after scale is not zero, do increment.
   810  			// e.g ceiling 3.0001 to scale 1, gets 3.1
   811  			idx := toIdx + (wordsFrac - wordsFracTo)
   812  			for idx > toIdx {
   813  				if d.wordBuf[idx] != 0 {
   814  					doInc = true
   815  					break
   816  				}
   817  				idx--
   818  			}
   819  		case 5:
   820  			digAfterScale := d.wordBuf[toIdx+1] / digMask // the first digit after scale.
   821  			// If first digit after scale is 5 and round even, do increment if digit at scale is odd.
   822  			doInc = (digAfterScale > 5) || (digAfterScale == 5)
   823  		case 10:
   824  			// Never round, just truncate.
   825  			doInc = false
   826  		}
   827  		if doInc {
   828  			if toIdx >= 0 {
   829  				to.wordBuf[toIdx]++
   830  			} else {
   831  				toIdx++
   832  				to.wordBuf[toIdx] = wordBase
   833  			}
   834  		} else if wordsInt+wordsFracTo == 0 {
   835  			*to = zeroMyDecimal
   836  			return nil
   837  		}
   838  	} else {
   839  		/* TODO - fix this code as it won't work for CEILING mode */
   840  		pos := wordsFracTo*digitsPerWord - frac - 1
   841  		shiftedNumber := to.wordBuf[toIdx] / powers10[pos]
   842  		digAfterScale := shiftedNumber % 10
   843  		if digAfterScale > roundDigit || (roundDigit == 5 && digAfterScale == 5) {
   844  			shiftedNumber += 10
   845  		}
   846  		to.wordBuf[toIdx] = powers10[pos] * (shiftedNumber - digAfterScale)
   847  	}
   848  	/*
   849  	   In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal words inside
   850  	   the buffer are as follows.
   851  
   852  	   Before <1, 5e8>
   853  	   After  <2, 5e8>
   854  
   855  	   Hence we need to set the 2nd field to 0.
   856  	   The same holds if we round 1.5e-9 to 2e-9.
   857  	*/
   858  	if wordsFracTo < wordsFrac {
   859  		idx := wordsInt + wordsFracTo
   860  		if frac == 0 && wordsInt == 0 {
   861  			idx = 1
   862  		}
   863  		for idx < wordBufLen {
   864  			to.wordBuf[idx] = 0
   865  			idx++
   866  		}
   867  	}
   868  
   869  	// Handle carry.
   870  	var carry int32
   871  	if to.wordBuf[toIdx] >= wordBase {
   872  		carry = 1
   873  		to.wordBuf[toIdx] -= wordBase
   874  		for carry == 1 && toIdx > 0 {
   875  			toIdx--
   876  			to.wordBuf[toIdx], carry = add(to.wordBuf[toIdx], 0, carry)
   877  		}
   878  		if carry > 0 {
   879  			if wordsInt+wordsFracTo >= wordBufLen {
   880  				wordsFracTo--
   881  				frac = wordsFracTo * digitsPerWord
   882  				err = ErrTruncated
   883  			}
   884  			for toIdx = wordsInt + myMax(wordsFracTo, 0); toIdx > 0; toIdx-- {
   885  				if toIdx < wordBufLen {
   886  					to.wordBuf[toIdx] = to.wordBuf[toIdx-1]
   887  				} else {
   888  					err = ErrOverflow
   889  				}
   890  			}
   891  			to.wordBuf[toIdx] = 1
   892  			/* We cannot have more than 9 * 9 = 81 digits. */
   893  			if int(to.digitsInt) < digitsPerWord*wordBufLen {
   894  				to.digitsInt++
   895  			} else {
   896  				err = ErrOverflow
   897  			}
   898  		}
   899  	} else {
   900  		for {
   901  			if to.wordBuf[toIdx] != 0 {
   902  				break
   903  			}
   904  			if toIdx == 0 {
   905  				/* making 'zero' with the proper scale */
   906  				idx := wordsFracTo + 1
   907  				to.digitsInt = 1
   908  				to.digitsFrac = int8(myMax(frac, 0))
   909  				to.negative = false
   910  				for toIdx < idx {
   911  					to.wordBuf[toIdx] = 0
   912  					toIdx++
   913  				}
   914  				to.resultFrac = to.digitsFrac
   915  				return nil
   916  			}
   917  			toIdx--
   918  		}
   919  	}
   920  	/* Here we check 999.9 -> 1000 case when we need to increase intDigCnt */
   921  	firstDig := to.digitsInt % digitsPerWord
   922  	if firstDig > 0 && to.wordBuf[toIdx] >= powers10[firstDig] {
   923  		to.digitsInt++
   924  	}
   925  	if frac < 0 {
   926  		frac = 0
   927  	}
   928  	to.digitsFrac = int8(frac)
   929  	to.resultFrac = to.digitsFrac
   930  	return
   931  }
   932  
   933  // FromInt sets the decimal value from int64.
   934  func (d *MyDecimal) FromInt(val int64) *MyDecimal {
   935  	var uVal uint64
   936  	if val < 0 {
   937  		d.negative = true
   938  		uVal = uint64(-val)
   939  	} else {
   940  		uVal = uint64(val)
   941  	}
   942  	return d.FromUint(uVal)
   943  }
   944  
   945  // FromUint sets the decimal value from uint64.
   946  func (d *MyDecimal) FromUint(val uint64) *MyDecimal {
   947  	x := val
   948  	wordIdx := 1
   949  	for x >= wordBase {
   950  		wordIdx++
   951  		x /= wordBase
   952  	}
   953  	d.digitsFrac = 0
   954  	d.digitsInt = int8(wordIdx * digitsPerWord)
   955  	x = val
   956  	for wordIdx > 0 {
   957  		wordIdx--
   958  		y := x / wordBase
   959  		d.wordBuf[wordIdx] = int32(x - y*wordBase)
   960  		x = y
   961  	}
   962  	return d
   963  }
   964  
   965  // ToInt returns int part of the decimal, returns the result and errcode.
   966  func (d *MyDecimal) ToInt() (int64, error) {
   967  	var x int64
   968  	wordIdx := 0
   969  	for i := d.digitsInt; i > 0; i -= digitsPerWord {
   970  		y := x
   971  		/*
   972  		   Attention: trick!
   973  		   we're calculating -|from| instead of |from| here
   974  		   because |LONGLONG_MIN| > LONGLONG_MAX
   975  		   so we can convert -9223372036854775808 correctly
   976  		*/
   977  		x = x*wordBase - int64(d.wordBuf[wordIdx])
   978  		wordIdx++
   979  		if y < math.MinInt64/wordBase || x > y {
   980  			/*
   981  			   the decimal is bigger than any possible integer
   982  			   return border integer depending on the sign
   983  			*/
   984  			if d.negative {
   985  				return math.MinInt64, ErrOverflow
   986  			}
   987  			return math.MaxInt64, ErrOverflow
   988  		}
   989  	}
   990  	/* boundary case: 9223372036854775808 */
   991  	if !d.negative && x == math.MinInt64 {
   992  		return math.MaxInt64, ErrOverflow
   993  	}
   994  	if !d.negative {
   995  		x = -x
   996  	}
   997  	for i := d.digitsFrac; i > 0; i -= digitsPerWord {
   998  		if d.wordBuf[wordIdx] != 0 {
   999  			return x, ErrTruncated
  1000  		}
  1001  		wordIdx++
  1002  	}
  1003  	return x, nil
  1004  }
  1005  
  1006  // ToUint returns int part of the decimal, returns the result and errcode.
  1007  func (d *MyDecimal) ToUint() (uint64, error) {
  1008  	if d.negative {
  1009  		return 0, ErrOverflow
  1010  	}
  1011  	var x uint64
  1012  	wordIdx := 0
  1013  	for i := d.digitsInt; i > 0; i -= digitsPerWord {
  1014  		y := x
  1015  		x = x*wordBase + uint64(d.wordBuf[wordIdx])
  1016  		wordIdx++
  1017  		if y > math.MaxUint64/wordBase || x < y {
  1018  			return math.MaxUint64, ErrOverflow
  1019  		}
  1020  	}
  1021  	for i := d.digitsFrac; i > 0; i -= digitsPerWord {
  1022  		if d.wordBuf[wordIdx] != 0 {
  1023  			return x, ErrTruncated
  1024  		}
  1025  		wordIdx++
  1026  	}
  1027  	return x, nil
  1028  }
  1029  
  1030  // FromFloat64 creates a decimal from float64 value.
  1031  func (d *MyDecimal) FromFloat64(f float64) error {
  1032  	s := strconv.FormatFloat(f, 'g', -1, 64)
  1033  	return d.FromString([]byte(s))
  1034  }
  1035  
  1036  // ToFloat64 converts decimal to float64 value.
  1037  func (d *MyDecimal) ToFloat64() (float64, error) {
  1038  	f, err := strconv.ParseFloat(d.String(), 64)
  1039  	if err != nil {
  1040  		err = ErrOverflow
  1041  	}
  1042  	return f, err
  1043  }
  1044  
  1045  /*
  1046  ToBin converts decimal to its binary fixed-length representation
  1047  two representations of the same length can be compared with memcmp
  1048  with the correct -1/0/+1 result
  1049  
  1050    PARAMS
  1051  		precision/frac - if precision is 0, internal value of the decimal will be used,
  1052  		then the encoded value is not memory comparable.
  1053  
  1054    NOTE
  1055      the buffer is assumed to be of the size decimalBinSize(precision, frac)
  1056  
  1057    RETURN VALUE
  1058    	bin     - binary value
  1059      errCode - eDecOK/eDecTruncate/eDecOverflow
  1060  
  1061    DESCRIPTION
  1062      for storage decimal numbers are converted to the "binary" format.
  1063  
  1064      This format has the following properties:
  1065        1. length of the binary representation depends on the {precision, frac}
  1066        as provided by the caller and NOT on the digitsInt/digitsFrac of the decimal to
  1067        convert.
  1068        2. binary representations of the same {precision, frac} can be compared
  1069        with memcmp - with the same result as DecimalCompare() of the original
  1070        decimals (not taking into account possible precision loss during
  1071        conversion).
  1072  
  1073      This binary format is as follows:
  1074        1. First the number is converted to have a requested precision and frac.
  1075        2. Every full digitsPerWord digits of digitsInt part are stored in 4 bytes
  1076           as is
  1077        3. The first digitsInt % digitesPerWord digits are stored in the reduced
  1078           number of bytes (enough bytes to store this number of digits -
  1079           see dig2bytes)
  1080        4. same for frac - full word are stored as is,
  1081           the last frac % digitsPerWord digits - in the reduced number of bytes.
  1082        5. If the number is negative - every byte is inversed.
  1083        5. The very first bit of the resulting byte array is inverted (because
  1084           memcmp compares unsigned bytes, see property 2 above)
  1085  
  1086      Example:
  1087  
  1088        1234567890.1234
  1089  
  1090      internally is represented as 3 words
  1091  
  1092        1 234567890 123400000
  1093  
  1094      (assuming we want a binary representation with precision=14, frac=4)
  1095      in hex it's
  1096  
  1097        00-00-00-01  0D-FB-38-D2  07-5A-EF-40
  1098  
  1099      now, middle word is full - it stores 9 decimal digits. It goes
  1100      into binary representation as is:
  1101  
  1102  
  1103        ...........  0D-FB-38-D2 ............
  1104  
  1105      First word has only one decimal digit. We can store one digit in
  1106      one byte, no need to waste four:
  1107  
  1108                  01 0D-FB-38-D2 ............
  1109  
  1110      now, last word. It's 123400000. We can store 1234 in two bytes:
  1111  
  1112                  01 0D-FB-38-D2 04-D2
  1113  
  1114      So, we've packed 12 bytes number in 7 bytes.
  1115      And now we invert the highest bit to get the final result:
  1116  
  1117                  81 0D FB 38 D2 04 D2
  1118  
  1119      And for -1234567890.1234 it would be
  1120  
  1121                  7E F2 04 C7 2D FB 2D
  1122  */
  1123  func (d *MyDecimal) ToBin(precision, frac int) ([]byte, error) {
  1124  	if precision > digitsPerWord*maxWordBufLen || precision < 0 || frac > mysql.MaxDecimalScale || frac < 0 {
  1125  		return nil, ErrBadNumber
  1126  	}
  1127  	var err error
  1128  	var mask int32
  1129  	if d.negative {
  1130  		mask = -1
  1131  	}
  1132  	digitsInt := precision - frac
  1133  	wordsInt := digitsInt / digitsPerWord
  1134  	leadingDigits := digitsInt - wordsInt*digitsPerWord
  1135  	wordsFrac := frac / digitsPerWord
  1136  	trailingDigits := frac - wordsFrac*digitsPerWord
  1137  
  1138  	wordsFracFrom := int(d.digitsFrac) / digitsPerWord
  1139  	trailingDigitsFrom := int(d.digitsFrac) - wordsFracFrom*digitsPerWord
  1140  	intSize := wordsInt*wordSize + dig2bytes[leadingDigits]
  1141  	fracSize := wordsFrac*wordSize + dig2bytes[trailingDigits]
  1142  	fracSizeFrom := wordsFracFrom*wordSize + dig2bytes[trailingDigitsFrom]
  1143  	originIntSize := intSize
  1144  	originFracSize := fracSize
  1145  	bin := make([]byte, intSize+fracSize)
  1146  	binIdx := 0
  1147  	wordIdxFrom, digitsIntFrom := d.removeLeadingZeros()
  1148  	if digitsIntFrom+fracSizeFrom == 0 {
  1149  		mask = 0
  1150  		digitsInt = 1
  1151  	}
  1152  
  1153  	wordsIntFrom := digitsIntFrom / digitsPerWord
  1154  	leadingDigitsFrom := digitsIntFrom - wordsIntFrom*digitsPerWord
  1155  	iSizeFrom := wordsIntFrom*wordSize + dig2bytes[leadingDigitsFrom]
  1156  
  1157  	if digitsInt < digitsIntFrom {
  1158  		wordIdxFrom += wordsIntFrom - wordsInt
  1159  		if leadingDigitsFrom > 0 {
  1160  			wordIdxFrom++
  1161  		}
  1162  		if leadingDigits > 0 {
  1163  			wordIdxFrom--
  1164  		}
  1165  		wordsIntFrom = wordsInt
  1166  		leadingDigitsFrom = leadingDigits
  1167  		err = ErrOverflow
  1168  	} else if intSize > iSizeFrom {
  1169  		for intSize > iSizeFrom {
  1170  			intSize--
  1171  			bin[binIdx] = byte(mask)
  1172  			binIdx++
  1173  		}
  1174  	}
  1175  
  1176  	if fracSize < fracSizeFrom {
  1177  		wordsFracFrom = wordsFrac
  1178  		trailingDigitsFrom = trailingDigits
  1179  		err = ErrTruncated
  1180  	} else if fracSize > fracSizeFrom && trailingDigitsFrom > 0 {
  1181  		if wordsFrac == wordsFracFrom {
  1182  			trailingDigitsFrom = trailingDigits
  1183  			fracSize = fracSizeFrom
  1184  		} else {
  1185  			wordsFracFrom++
  1186  			trailingDigitsFrom = 0
  1187  		}
  1188  	}
  1189  	// xIntFrom part
  1190  	if leadingDigitsFrom > 0 {
  1191  		i := dig2bytes[leadingDigitsFrom]
  1192  		x := (d.wordBuf[wordIdxFrom] % powers10[leadingDigitsFrom]) ^ mask
  1193  		wordIdxFrom++
  1194  		writeWord(bin[binIdx:], x, i)
  1195  		binIdx += i
  1196  	}
  1197  
  1198  	// wordsInt + wordsFrac part.
  1199  	for stop := wordIdxFrom + wordsIntFrom + wordsFracFrom; wordIdxFrom < stop; binIdx += wordSize {
  1200  		x := d.wordBuf[wordIdxFrom] ^ mask
  1201  		wordIdxFrom++
  1202  		writeWord(bin[binIdx:], x, 4)
  1203  	}
  1204  
  1205  	// xFracFrom part
  1206  	if trailingDigitsFrom > 0 {
  1207  		var x int32
  1208  		i := dig2bytes[trailingDigitsFrom]
  1209  		lim := trailingDigits
  1210  		if wordsFracFrom < wordsFrac {
  1211  			lim = digitsPerWord
  1212  		}
  1213  
  1214  		for trailingDigitsFrom < lim && dig2bytes[trailingDigitsFrom] == i {
  1215  			trailingDigitsFrom++
  1216  		}
  1217  		x = (d.wordBuf[wordIdxFrom] / powers10[digitsPerWord-trailingDigitsFrom]) ^ mask
  1218  		writeWord(bin[binIdx:], x, i)
  1219  		binIdx += i
  1220  	}
  1221  	if fracSize > fracSizeFrom {
  1222  		binIdxEnd := originIntSize + originFracSize
  1223  		for fracSize > fracSizeFrom && binIdx < binIdxEnd {
  1224  			fracSize--
  1225  			bin[binIdx] = byte(mask)
  1226  			binIdx++
  1227  		}
  1228  	}
  1229  	bin[0] ^= 0x80
  1230  	return bin, err
  1231  }
  1232  
  1233  // ToHashKey removes the leading and trailing zeros and generates a hash key.
  1234  // Two Decimals dec0 and dec1 with different fraction will generate the same hash keys if dec0.Compare(dec1) == 0.
  1235  func (d *MyDecimal) ToHashKey() ([]byte, error) {
  1236  	_, digitsInt := d.removeLeadingZeros()
  1237  	_, digitsFrac := d.removeTrailingZeros()
  1238  	prec := digitsInt + digitsFrac
  1239  	if prec == 0 { // zeroDecimal
  1240  		prec = 1
  1241  	}
  1242  	buf, err := d.ToBin(prec, digitsFrac)
  1243  	if err == ErrTruncated {
  1244  		// This err is caused by shorter digitsFrac;
  1245  		// After removing the trailing zeros from a Decimal,
  1246  		// so digitsFrac may be less than the real digitsFrac of the Decimal,
  1247  		// thus ErrTruncated may be raised, we can ignore it here.
  1248  		err = nil
  1249  	}
  1250  	return buf, err
  1251  }
  1252  
  1253  // PrecisionAndFrac returns the internal precision and frac number.
  1254  func (d *MyDecimal) PrecisionAndFrac() (precision, frac int) {
  1255  	frac = int(d.digitsFrac)
  1256  	_, digitsInt := d.removeLeadingZeros()
  1257  	precision = digitsInt + frac
  1258  	if precision == 0 {
  1259  		precision = 1
  1260  	}
  1261  	return
  1262  }
  1263  
  1264  // IsZero checks whether it's a zero decimal.
  1265  func (d *MyDecimal) IsZero() bool {
  1266  	isZero := true
  1267  	for _, val := range d.wordBuf {
  1268  		if val != 0 {
  1269  			isZero = false
  1270  			break
  1271  		}
  1272  	}
  1273  	return isZero
  1274  }
  1275  
  1276  // FromBin Restores decimal from its binary fixed-length representation.
  1277  func (d *MyDecimal) FromBin(bin []byte, precision, frac int) (binSize int, err error) {
  1278  	if len(bin) == 0 {
  1279  		*d = zeroMyDecimal
  1280  		return 0, ErrBadNumber
  1281  	}
  1282  	digitsInt := precision - frac
  1283  	wordsInt := digitsInt / digitsPerWord
  1284  	leadingDigits := digitsInt - wordsInt*digitsPerWord
  1285  	wordsFrac := frac / digitsPerWord
  1286  	trailingDigits := frac - wordsFrac*digitsPerWord
  1287  	wordsIntTo := wordsInt
  1288  	if leadingDigits > 0 {
  1289  		wordsIntTo++
  1290  	}
  1291  	wordsFracTo := wordsFrac
  1292  	if trailingDigits > 0 {
  1293  		wordsFracTo++
  1294  	}
  1295  
  1296  	binIdx := 0
  1297  	mask := int32(-1)
  1298  	if bin[binIdx]&0x80 > 0 {
  1299  		mask = 0
  1300  	}
  1301  	binSize = decimalBinSize(precision, frac)
  1302  	dCopy := make([]byte, 40)
  1303  	dCopy = dCopy[:binSize]
  1304  	copy(dCopy, bin)
  1305  	dCopy[0] ^= 0x80
  1306  	bin = dCopy
  1307  	oldWordsIntTo := wordsIntTo
  1308  	wordsIntTo, wordsFracTo, err = fixWordCntError(wordsIntTo, wordsFracTo)
  1309  	if err != nil {
  1310  		if wordsIntTo < oldWordsIntTo {
  1311  			binIdx += dig2bytes[leadingDigits] + (wordsInt-wordsIntTo)*wordSize
  1312  		} else {
  1313  			trailingDigits = 0
  1314  			wordsFrac = wordsFracTo
  1315  		}
  1316  	}
  1317  	d.negative = mask != 0
  1318  	d.digitsInt = int8(wordsInt*digitsPerWord + leadingDigits)
  1319  	d.digitsFrac = int8(wordsFrac*digitsPerWord + trailingDigits)
  1320  
  1321  	wordIdx := 0
  1322  	if leadingDigits > 0 {
  1323  		i := dig2bytes[leadingDigits]
  1324  		x := readWord(bin[binIdx:], i)
  1325  		binIdx += i
  1326  		d.wordBuf[wordIdx] = x ^ mask
  1327  		if uint64(d.wordBuf[wordIdx]) >= uint64(powers10[leadingDigits+1]) {
  1328  			*d = zeroMyDecimal
  1329  			return binSize, ErrBadNumber
  1330  		}
  1331  		if wordIdx > 0 || d.wordBuf[wordIdx] != 0 {
  1332  			wordIdx++
  1333  		} else {
  1334  			d.digitsInt -= int8(leadingDigits)
  1335  		}
  1336  	}
  1337  	for stop := binIdx + wordsInt*wordSize; binIdx < stop; binIdx += wordSize {
  1338  		d.wordBuf[wordIdx] = readWord(bin[binIdx:], 4) ^ mask
  1339  		if uint32(d.wordBuf[wordIdx]) > wordMax {
  1340  			*d = zeroMyDecimal
  1341  			return binSize, ErrBadNumber
  1342  		}
  1343  		if wordIdx > 0 || d.wordBuf[wordIdx] != 0 {
  1344  			wordIdx++
  1345  		} else {
  1346  			d.digitsInt -= digitsPerWord
  1347  		}
  1348  	}
  1349  
  1350  	for stop := binIdx + wordsFrac*wordSize; binIdx < stop; binIdx += wordSize {
  1351  		d.wordBuf[wordIdx] = readWord(bin[binIdx:], 4) ^ mask
  1352  		if uint32(d.wordBuf[wordIdx]) > wordMax {
  1353  			*d = zeroMyDecimal
  1354  			return binSize, ErrBadNumber
  1355  		}
  1356  		wordIdx++
  1357  	}
  1358  
  1359  	if trailingDigits > 0 {
  1360  		i := dig2bytes[trailingDigits]
  1361  		x := readWord(bin[binIdx:], i)
  1362  		d.wordBuf[wordIdx] = (x ^ mask) * powers10[digitsPerWord-trailingDigits]
  1363  		if uint32(d.wordBuf[wordIdx]) > wordMax {
  1364  			*d = zeroMyDecimal
  1365  			return binSize, ErrBadNumber
  1366  		}
  1367  	}
  1368  
  1369  	if d.digitsInt == 0 && d.digitsFrac == 0 {
  1370  		*d = zeroMyDecimal
  1371  	}
  1372  	d.resultFrac = int8(frac)
  1373  	return binSize, err
  1374  }
  1375  
  1376  // decimalBinSize returns the size of array to hold a binary representation of a decimal.
  1377  func decimalBinSize(precision, frac int) int {
  1378  	digitsInt := precision - frac
  1379  	wordsInt := digitsInt / digitsPerWord
  1380  	wordsFrac := frac / digitsPerWord
  1381  	xInt := digitsInt - wordsInt*digitsPerWord
  1382  	xFrac := frac - wordsFrac*digitsPerWord
  1383  	return wordsInt*wordSize + dig2bytes[xInt] + wordsFrac*wordSize + dig2bytes[xFrac]
  1384  }
  1385  
  1386  func readWord(b []byte, size int) int32 {
  1387  	var x int32
  1388  	switch size {
  1389  	case 1:
  1390  		x = int32(int8(b[0]))
  1391  	case 2:
  1392  		x = int32(int8(b[0]))<<8 + int32(b[1])
  1393  	case 3:
  1394  		if b[0]&128 > 0 {
  1395  			x = int32(uint32(255)<<24 | uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2]))
  1396  		} else {
  1397  			x = int32(uint32(b[0])<<16 | uint32(b[1])<<8 | uint32(b[2]))
  1398  		}
  1399  	case 4:
  1400  		x = int32(b[3]) + int32(b[2])<<8 + int32(b[1])<<16 + int32(int8(b[0]))<<24
  1401  	}
  1402  	return x
  1403  }
  1404  
  1405  func writeWord(b []byte, word int32, size int) {
  1406  	v := uint32(word)
  1407  	switch size {
  1408  	case 1:
  1409  		b[0] = byte(word)
  1410  	case 2:
  1411  		b[0] = byte(v >> 8)
  1412  		b[1] = byte(v)
  1413  	case 3:
  1414  		b[0] = byte(v >> 16)
  1415  		b[1] = byte(v >> 8)
  1416  		b[2] = byte(v)
  1417  	case 4:
  1418  		b[0] = byte(v >> 24)
  1419  		b[1] = byte(v >> 16)
  1420  		b[2] = byte(v >> 8)
  1421  		b[3] = byte(v)
  1422  	}
  1423  }
  1424  
  1425  // Compare compares one decimal to another, returns -1/0/1.
  1426  func (d *MyDecimal) Compare(to *MyDecimal) int {
  1427  	if d.negative == to.negative {
  1428  		cmp, err := doSub(d, to, nil)
  1429  		terror.Log(errors.Trace(err))
  1430  		return cmp
  1431  	}
  1432  	if d.negative {
  1433  		return -1
  1434  	}
  1435  	return 1
  1436  }
  1437  
  1438  // DecimalNeg reverses decimal's sign.
  1439  func DecimalNeg(from *MyDecimal) *MyDecimal {
  1440  	to := *from
  1441  	if from.IsZero() {
  1442  		return &to
  1443  	}
  1444  	to.negative = !from.negative
  1445  	return &to
  1446  }
  1447  
  1448  // DecimalAdd adds two decimals, sets the result to 'to'.
  1449  // Note: DO NOT use `from1` or `from2` as `to` since the metadata
  1450  // of `to` may be changed during evaluating.
  1451  func DecimalAdd(from1, from2, to *MyDecimal) error {
  1452  	to.resultFrac = myMaxInt8(from1.resultFrac, from2.resultFrac)
  1453  	if from1.negative == from2.negative {
  1454  		return doAdd(from1, from2, to)
  1455  	}
  1456  	_, err := doSub(from1, from2, to)
  1457  	return err
  1458  }
  1459  
  1460  // DecimalSub subs one decimal from another, sets the result to 'to'.
  1461  func DecimalSub(from1, from2, to *MyDecimal) error {
  1462  	to.resultFrac = myMaxInt8(from1.resultFrac, from2.resultFrac)
  1463  	if from1.negative == from2.negative {
  1464  		_, err := doSub(from1, from2, to)
  1465  		return err
  1466  	}
  1467  	return doAdd(from1, from2, to)
  1468  }
  1469  
  1470  func doSub(from1, from2, to *MyDecimal) (cmp int, err error) {
  1471  	var (
  1472  		wordsInt1   = digitsToWords(int(from1.digitsInt))
  1473  		wordsFrac1  = digitsToWords(int(from1.digitsFrac))
  1474  		wordsInt2   = digitsToWords(int(from2.digitsInt))
  1475  		wordsFrac2  = digitsToWords(int(from2.digitsFrac))
  1476  		wordsFracTo = myMax(wordsFrac1, wordsFrac2)
  1477  
  1478  		start1 = 0
  1479  		stop1  = wordsInt1
  1480  		idx1   = 0
  1481  		start2 = 0
  1482  		stop2  = wordsInt2
  1483  		idx2   = 0
  1484  	)
  1485  	if from1.wordBuf[idx1] == 0 {
  1486  		for idx1 < stop1 && from1.wordBuf[idx1] == 0 {
  1487  			idx1++
  1488  		}
  1489  		start1 = idx1
  1490  		wordsInt1 = stop1 - idx1
  1491  	}
  1492  	if from2.wordBuf[idx2] == 0 {
  1493  		for idx2 < stop2 && from2.wordBuf[idx2] == 0 {
  1494  			idx2++
  1495  		}
  1496  		start2 = idx2
  1497  		wordsInt2 = stop2 - idx2
  1498  	}
  1499  
  1500  	var carry int32
  1501  	if wordsInt2 > wordsInt1 {
  1502  		carry = 1
  1503  	} else if wordsInt2 == wordsInt1 {
  1504  		end1 := stop1 + wordsFrac1 - 1
  1505  		end2 := stop2 + wordsFrac2 - 1
  1506  		for idx1 <= end1 && from1.wordBuf[end1] == 0 {
  1507  			end1--
  1508  		}
  1509  		for idx2 <= end2 && from2.wordBuf[end2] == 0 {
  1510  			end2--
  1511  		}
  1512  		wordsFrac1 = end1 - stop1 + 1
  1513  		wordsFrac2 = end2 - stop2 + 1
  1514  		for idx1 <= end1 && idx2 <= end2 && from1.wordBuf[idx1] == from2.wordBuf[idx2] {
  1515  			idx1++
  1516  			idx2++
  1517  		}
  1518  		if idx1 <= end1 {
  1519  			if idx2 <= end2 && from2.wordBuf[idx2] > from1.wordBuf[idx1] {
  1520  				carry = 1
  1521  			} else {
  1522  				carry = 0
  1523  			}
  1524  		} else {
  1525  			if idx2 <= end2 {
  1526  				carry = 1
  1527  			} else {
  1528  				if to == nil {
  1529  					return 0, nil
  1530  				}
  1531  				*to = zeroMyDecimal
  1532  				return 0, nil
  1533  			}
  1534  		}
  1535  	}
  1536  
  1537  	if to == nil {
  1538  		if carry > 0 == from1.negative { // from2 is negative too.
  1539  			return 1, nil
  1540  		}
  1541  		return -1, nil
  1542  	}
  1543  
  1544  	to.negative = from1.negative
  1545  
  1546  	/* ensure that always idx1 > idx2 (and wordsInt1 >= wordsInt2) */
  1547  	if carry > 0 {
  1548  		from1, from2 = from2, from1
  1549  		start1, start2 = start2, start1
  1550  		wordsInt1, wordsInt2 = wordsInt2, wordsInt1
  1551  		wordsFrac1, wordsFrac2 = wordsFrac2, wordsFrac1
  1552  		to.negative = !to.negative
  1553  	}
  1554  
  1555  	wordsInt1, wordsFracTo, err = fixWordCntError(wordsInt1, wordsFracTo)
  1556  	idxTo := wordsInt1 + wordsFracTo
  1557  	to.digitsFrac = from1.digitsFrac
  1558  	if to.digitsFrac < from2.digitsFrac {
  1559  		to.digitsFrac = from2.digitsFrac
  1560  	}
  1561  	to.digitsInt = int8(wordsInt1 * digitsPerWord)
  1562  	if err != nil {
  1563  		if to.digitsFrac > int8(wordsFracTo*digitsPerWord) {
  1564  			to.digitsFrac = int8(wordsFracTo * digitsPerWord)
  1565  		}
  1566  		if wordsFrac1 > wordsFracTo {
  1567  			wordsFrac1 = wordsFracTo
  1568  		}
  1569  		if wordsFrac2 > wordsFracTo {
  1570  			wordsFrac2 = wordsFracTo
  1571  		}
  1572  		if wordsInt2 > wordsInt1 {
  1573  			wordsInt2 = wordsInt1
  1574  		}
  1575  	}
  1576  	carry = 0
  1577  
  1578  	/* part 1 - max(frac) ... min (frac) */
  1579  	if wordsFrac1 > wordsFrac2 {
  1580  		idx1 = start1 + wordsInt1 + wordsFrac1
  1581  		stop1 = start1 + wordsInt1 + wordsFrac2
  1582  		idx2 = start2 + wordsInt2 + wordsFrac2
  1583  		for wordsFracTo > wordsFrac1 {
  1584  			wordsFracTo--
  1585  			idxTo--
  1586  			to.wordBuf[idxTo] = 0
  1587  		}
  1588  		for idx1 > stop1 {
  1589  			idxTo--
  1590  			idx1--
  1591  			to.wordBuf[idxTo] = from1.wordBuf[idx1]
  1592  		}
  1593  	} else {
  1594  		idx1 = start1 + wordsInt1 + wordsFrac1
  1595  		idx2 = start2 + wordsInt2 + wordsFrac2
  1596  		stop2 = start2 + wordsInt2 + wordsFrac1
  1597  		for wordsFracTo > wordsFrac2 {
  1598  			wordsFracTo--
  1599  			idxTo--
  1600  			to.wordBuf[idxTo] = 0
  1601  		}
  1602  		for idx2 > stop2 {
  1603  			idxTo--
  1604  			idx2--
  1605  			to.wordBuf[idxTo], carry = sub(0, from2.wordBuf[idx2], carry)
  1606  		}
  1607  	}
  1608  
  1609  	/* part 2 - min(frac) ... wordsInt2 */
  1610  	for idx2 > start2 {
  1611  		idxTo--
  1612  		idx1--
  1613  		idx2--
  1614  		to.wordBuf[idxTo], carry = sub(from1.wordBuf[idx1], from2.wordBuf[idx2], carry)
  1615  	}
  1616  
  1617  	/* part 3 - wordsInt2 ... wordsInt1 */
  1618  	for carry > 0 && idx1 > start1 {
  1619  		idxTo--
  1620  		idx1--
  1621  		to.wordBuf[idxTo], carry = sub(from1.wordBuf[idx1], 0, carry)
  1622  	}
  1623  	for idx1 > start1 {
  1624  		idxTo--
  1625  		idx1--
  1626  		to.wordBuf[idxTo] = from1.wordBuf[idx1]
  1627  	}
  1628  	for idxTo > 0 {
  1629  		idxTo--
  1630  		to.wordBuf[idxTo] = 0
  1631  	}
  1632  	return 0, err
  1633  }
  1634  
  1635  func doAdd(from1, from2, to *MyDecimal) error {
  1636  	var (
  1637  		err         error
  1638  		wordsInt1   = digitsToWords(int(from1.digitsInt))
  1639  		wordsFrac1  = digitsToWords(int(from1.digitsFrac))
  1640  		wordsInt2   = digitsToWords(int(from2.digitsInt))
  1641  		wordsFrac2  = digitsToWords(int(from2.digitsFrac))
  1642  		wordsIntTo  = myMax(wordsInt1, wordsInt2)
  1643  		wordsFracTo = myMax(wordsFrac1, wordsFrac2)
  1644  	)
  1645  
  1646  	var x int32
  1647  	if wordsInt1 > wordsInt2 {
  1648  		x = from1.wordBuf[0]
  1649  	} else if wordsInt2 > wordsInt1 {
  1650  		x = from2.wordBuf[0]
  1651  	} else {
  1652  		x = from1.wordBuf[0] + from2.wordBuf[0]
  1653  	}
  1654  	if x > wordMax-1 { /* yes, there is */
  1655  		wordsIntTo++
  1656  		to.wordBuf[0] = 0 /* safety */
  1657  	}
  1658  
  1659  	wordsIntTo, wordsFracTo, err = fixWordCntError(wordsIntTo, wordsFracTo)
  1660  	if err == ErrOverflow {
  1661  		maxDecimal(wordBufLen*digitsPerWord, 0, to)
  1662  		return err
  1663  	}
  1664  	idxTo := wordsIntTo + wordsFracTo
  1665  	to.negative = from1.negative
  1666  	to.digitsInt = int8(wordsIntTo * digitsPerWord)
  1667  	to.digitsFrac = myMaxInt8(from1.digitsFrac, from2.digitsFrac)
  1668  
  1669  	if err != nil {
  1670  		if to.digitsFrac > int8(wordsFracTo*digitsPerWord) {
  1671  			to.digitsFrac = int8(wordsFracTo * digitsPerWord)
  1672  		}
  1673  		if wordsFrac1 > wordsFracTo {
  1674  			wordsFrac1 = wordsFracTo
  1675  		}
  1676  		if wordsFrac2 > wordsFracTo {
  1677  			wordsFrac2 = wordsFracTo
  1678  		}
  1679  		if wordsInt1 > wordsIntTo {
  1680  			wordsInt1 = wordsIntTo
  1681  		}
  1682  		if wordsInt2 > wordsIntTo {
  1683  			wordsInt2 = wordsIntTo
  1684  		}
  1685  	}
  1686  	var dec1, dec2 = from1, from2
  1687  	var idx1, idx2, stop, stop2 int
  1688  	/* part 1 - max(frac) ... min (frac) */
  1689  	if wordsFrac1 > wordsFrac2 {
  1690  		idx1 = wordsInt1 + wordsFrac1
  1691  		stop = wordsInt1 + wordsFrac2
  1692  		idx2 = wordsInt2 + wordsFrac2
  1693  		if wordsInt1 > wordsInt2 {
  1694  			stop2 = wordsInt1 - wordsInt2
  1695  		}
  1696  	} else {
  1697  		idx1 = wordsInt2 + wordsFrac2
  1698  		stop = wordsInt2 + wordsFrac1
  1699  		idx2 = wordsInt1 + wordsFrac1
  1700  		if wordsInt2 > wordsInt1 {
  1701  			stop2 = wordsInt2 - wordsInt1
  1702  		}
  1703  		dec1, dec2 = from2, from1
  1704  	}
  1705  	for idx1 > stop {
  1706  		idxTo--
  1707  		idx1--
  1708  		to.wordBuf[idxTo] = dec1.wordBuf[idx1]
  1709  	}
  1710  
  1711  	/* part 2 - min(frac) ... min(digitsInt) */
  1712  	carry := int32(0)
  1713  	for idx1 > stop2 {
  1714  		idx1--
  1715  		idx2--
  1716  		idxTo--
  1717  		to.wordBuf[idxTo], carry = add(dec1.wordBuf[idx1], dec2.wordBuf[idx2], carry)
  1718  	}
  1719  
  1720  	/* part 3 - min(digitsInt) ... max(digitsInt) */
  1721  	stop = 0
  1722  	if wordsInt1 > wordsInt2 {
  1723  		idx1 = wordsInt1 - wordsInt2
  1724  		dec1, dec2 = from1, from2
  1725  	} else {
  1726  		idx1 = wordsInt2 - wordsInt1
  1727  		dec1, dec2 = from2, from1
  1728  	}
  1729  	for idx1 > stop {
  1730  		idxTo--
  1731  		idx1--
  1732  		to.wordBuf[idxTo], carry = add(dec1.wordBuf[idx1], 0, carry)
  1733  	}
  1734  	if carry > 0 {
  1735  		idxTo--
  1736  		to.wordBuf[idxTo] = 1
  1737  	}
  1738  	return err
  1739  }
  1740  
  1741  func maxDecimal(precision, frac int, to *MyDecimal) {
  1742  	digitsInt := precision - frac
  1743  	to.negative = false
  1744  	to.digitsInt = int8(digitsInt)
  1745  	idx := 0
  1746  	if digitsInt > 0 {
  1747  		firstWordDigits := digitsInt % digitsPerWord
  1748  		if firstWordDigits > 0 {
  1749  			to.wordBuf[idx] = powers10[firstWordDigits] - 1 /* get 9 99 999 ... */
  1750  			idx++
  1751  		}
  1752  		for digitsInt /= digitsPerWord; digitsInt > 0; digitsInt-- {
  1753  			to.wordBuf[idx] = wordMax
  1754  			idx++
  1755  		}
  1756  	}
  1757  	to.digitsFrac = int8(frac)
  1758  	if frac > 0 {
  1759  		lastDigits := frac % digitsPerWord
  1760  		for frac /= digitsPerWord; frac > 0; frac-- {
  1761  			to.wordBuf[idx] = wordMax
  1762  			idx++
  1763  		}
  1764  		if lastDigits > 0 {
  1765  			to.wordBuf[idx] = fracMax[lastDigits-1]
  1766  		}
  1767  	}
  1768  }
  1769  
  1770  /*
  1771  DecimalMul multiplies two decimals.
  1772  
  1773        from1, from2 - factors
  1774        to      - product
  1775  
  1776    RETURN VALUE
  1777      E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW;
  1778  
  1779    NOTES
  1780      in this implementation, with wordSize=4 we have digitsPerWord=9,
  1781      and 63-digit number will take only 7 words (basically a 7-digit
  1782      "base 999999999" number).  Thus there's no need in fast multiplication
  1783      algorithms, 7-digit numbers can be multiplied with a naive O(n*n)
  1784      method.
  1785  
  1786      XXX if this library is to be used with huge numbers of thousands of
  1787      digits, fast multiplication must be implemented.
  1788  */
  1789  func DecimalMul(from1, from2, to *MyDecimal) error {
  1790  	var (
  1791  		err         error
  1792  		wordsInt1   = digitsToWords(int(from1.digitsInt))
  1793  		wordsFrac1  = digitsToWords(int(from1.digitsFrac))
  1794  		wordsInt2   = digitsToWords(int(from2.digitsInt))
  1795  		wordsFrac2  = digitsToWords(int(from2.digitsFrac))
  1796  		wordsIntTo  = digitsToWords(int(from1.digitsInt) + int(from2.digitsInt))
  1797  		wordsFracTo = wordsFrac1 + wordsFrac2
  1798  		idx1        = wordsInt1
  1799  		idx2        = wordsInt2
  1800  		idxTo       int
  1801  		tmp1        = wordsIntTo
  1802  		tmp2        = wordsFracTo
  1803  	)
  1804  	to.resultFrac = myMinInt8(from1.resultFrac+from2.resultFrac, mysql.MaxDecimalScale)
  1805  	wordsIntTo, wordsFracTo, err = fixWordCntError(wordsIntTo, wordsFracTo)
  1806  	to.negative = from1.negative != from2.negative
  1807  	to.digitsFrac = from1.digitsFrac + from2.digitsFrac
  1808  	if to.digitsFrac > notFixedDec {
  1809  		to.digitsFrac = notFixedDec
  1810  	}
  1811  	to.digitsInt = int8(wordsIntTo * digitsPerWord)
  1812  	if err == ErrOverflow {
  1813  		return err
  1814  	}
  1815  	if err != nil {
  1816  		if to.digitsFrac > int8(wordsFracTo*digitsPerWord) {
  1817  			to.digitsFrac = int8(wordsFracTo * digitsPerWord)
  1818  		}
  1819  		if to.digitsInt > int8(wordsIntTo*digitsPerWord) {
  1820  			to.digitsInt = int8(wordsIntTo * digitsPerWord)
  1821  		}
  1822  		if tmp1 > wordsIntTo {
  1823  			tmp1 -= wordsIntTo
  1824  			tmp2 = tmp1 >> 1
  1825  			wordsInt2 -= tmp1 - tmp2
  1826  			wordsFrac1 = 0
  1827  			wordsFrac2 = 0
  1828  		} else {
  1829  			tmp2 -= wordsFracTo
  1830  			tmp1 = tmp2 >> 1
  1831  			if wordsFrac1 <= wordsFrac2 {
  1832  				wordsFrac1 -= tmp1
  1833  				wordsFrac2 -= tmp2 - tmp1
  1834  			} else {
  1835  				wordsFrac2 -= tmp1
  1836  				wordsFrac1 -= tmp2 - tmp1
  1837  			}
  1838  		}
  1839  	}
  1840  	startTo := wordsIntTo + wordsFracTo - 1
  1841  	start2 := idx2 + wordsFrac2 - 1
  1842  	stop1 := idx1 - wordsInt1
  1843  	stop2 := idx2 - wordsInt2
  1844  	to.wordBuf = zeroMyDecimal.wordBuf
  1845  
  1846  	for idx1 += wordsFrac1 - 1; idx1 >= stop1; idx1-- {
  1847  		carry := int32(0)
  1848  		idxTo = startTo
  1849  		idx2 = start2
  1850  		for idx2 >= stop2 {
  1851  			var hi, lo int32
  1852  			p := int64(from1.wordBuf[idx1]) * int64(from2.wordBuf[idx2])
  1853  			hi = int32(p / wordBase)
  1854  			lo = int32(p - int64(hi)*wordBase)
  1855  			to.wordBuf[idxTo], carry = add2(to.wordBuf[idxTo], lo, carry)
  1856  			carry += hi
  1857  			idx2--
  1858  			idxTo--
  1859  		}
  1860  		if carry > 0 {
  1861  			if idxTo < 0 {
  1862  				return ErrOverflow
  1863  			}
  1864  			to.wordBuf[idxTo], carry = add2(to.wordBuf[idxTo], 0, carry)
  1865  		}
  1866  		for idxTo--; carry > 0; idxTo-- {
  1867  			if idxTo < 0 {
  1868  				return ErrOverflow
  1869  			}
  1870  			to.wordBuf[idxTo], carry = add(to.wordBuf[idxTo], 0, carry)
  1871  		}
  1872  		startTo--
  1873  	}
  1874  
  1875  	/* Now we have to check for -0.000 case */
  1876  	if to.negative {
  1877  		idx := 0
  1878  		end := wordsIntTo + wordsFracTo
  1879  		for {
  1880  			if to.wordBuf[idx] != 0 {
  1881  				break
  1882  			}
  1883  			idx++
  1884  			/* We got decimal zero */
  1885  			if idx == end {
  1886  				*to = zeroMyDecimal
  1887  				break
  1888  			}
  1889  		}
  1890  	}
  1891  
  1892  	idxTo = 0
  1893  	dToMove := wordsIntTo + digitsToWords(int(to.digitsFrac))
  1894  	for to.wordBuf[idxTo] == 0 && to.digitsInt > digitsPerWord {
  1895  		idxTo++
  1896  		to.digitsInt -= digitsPerWord
  1897  		dToMove--
  1898  	}
  1899  	if idxTo > 0 {
  1900  		curIdx := 0
  1901  		for dToMove > 0 {
  1902  			to.wordBuf[curIdx] = to.wordBuf[idxTo]
  1903  			curIdx++
  1904  			idxTo++
  1905  			dToMove--
  1906  		}
  1907  	}
  1908  	return err
  1909  }
  1910  
  1911  // DecimalDiv does division of two decimals.
  1912  //
  1913  // from1    - dividend
  1914  // from2    - divisor
  1915  // to       - quotient
  1916  // fracIncr - increment of fraction
  1917  func DecimalDiv(from1, from2, to *MyDecimal, fracIncr int) error {
  1918  	to.resultFrac = myMinInt8(from1.resultFrac+int8(fracIncr), mysql.MaxDecimalScale)
  1919  	return doDivMod(from1, from2, to, nil, fracIncr)
  1920  }
  1921  
  1922  /*
  1923  DecimalMod does modulus of two decimals.
  1924  
  1925        from1   - dividend
  1926        from2   - divisor
  1927        to      - modulus
  1928  
  1929    RETURN VALUE
  1930      E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_DIV_ZERO;
  1931  
  1932    NOTES
  1933      see do_div_mod()
  1934  
  1935    DESCRIPTION
  1936      the modulus R in    R = M mod N
  1937  
  1938     is defined as
  1939  
  1940       0 <= |R| < |M|
  1941       sign R == sign M
  1942       R = M - k*N, where k is integer
  1943  
  1944     thus, there's no requirement for M or N to be integers
  1945  */
  1946  func DecimalMod(from1, from2, to *MyDecimal) error {
  1947  	to.resultFrac = myMaxInt8(from1.resultFrac, from2.resultFrac)
  1948  	return doDivMod(from1, from2, nil, to, 0)
  1949  }
  1950  
  1951  func doDivMod(from1, from2, to, mod *MyDecimal, fracIncr int) error {
  1952  	var (
  1953  		frac1 = digitsToWords(int(from1.digitsFrac)) * digitsPerWord
  1954  		prec1 = int(from1.digitsInt) + frac1
  1955  		frac2 = digitsToWords(int(from2.digitsFrac)) * digitsPerWord
  1956  		prec2 = int(from2.digitsInt) + frac2
  1957  	)
  1958  	if mod != nil {
  1959  		to = mod
  1960  	}
  1961  
  1962  	/* removing all the leading zeros */
  1963  	i := ((prec2 - 1) % digitsPerWord) + 1
  1964  	idx2 := 0
  1965  	for prec2 > 0 && from2.wordBuf[idx2] == 0 {
  1966  		prec2 -= i
  1967  		i = digitsPerWord
  1968  		idx2++
  1969  	}
  1970  	if prec2 <= 0 {
  1971  		/* short-circuit everything: from2 == 0 */
  1972  		return ErrDivByZero
  1973  	}
  1974  
  1975  	prec2 -= countLeadingZeroes((prec2-1)%digitsPerWord, from2.wordBuf[idx2])
  1976  	i = ((prec1 - 1) % digitsPerWord) + 1
  1977  	idx1 := 0
  1978  	for prec1 > 0 && from1.wordBuf[idx1] == 0 {
  1979  		prec1 -= i
  1980  		i = digitsPerWord
  1981  		idx1++
  1982  	}
  1983  	if prec1 <= 0 {
  1984  		/* short-circuit everything: from1 == 0 */
  1985  		*to = zeroMyDecimal
  1986  		return nil
  1987  	}
  1988  	prec1 -= countLeadingZeroes((prec1-1)%digitsPerWord, from1.wordBuf[idx1])
  1989  
  1990  	/* let's fix fracIncr, taking into account frac1,frac2 increase */
  1991  	fracIncr -= frac1 - int(from1.digitsFrac) + frac2 - int(from2.digitsFrac)
  1992  	if fracIncr < 0 {
  1993  		fracIncr = 0
  1994  	}
  1995  
  1996  	digitsIntTo := (prec1 - frac1) - (prec2 - frac2)
  1997  	if from1.wordBuf[idx1] >= from2.wordBuf[idx2] {
  1998  		digitsIntTo++
  1999  	}
  2000  	var wordsIntTo int
  2001  	if digitsIntTo < 0 {
  2002  		digitsIntTo /= digitsPerWord
  2003  		wordsIntTo = 0
  2004  	} else {
  2005  		wordsIntTo = digitsToWords(digitsIntTo)
  2006  	}
  2007  	var wordsFracTo int
  2008  	var err error
  2009  	if mod != nil {
  2010  		// we're calculating N1 % N2.
  2011  		// The result will have
  2012  		// digitsFrac=max(frac1, frac2), as for subtraction
  2013  		// digitsInt=from2.digitsInt
  2014  		to.negative = from1.negative
  2015  		to.digitsFrac = myMaxInt8(from1.digitsFrac, from2.digitsFrac)
  2016  	} else {
  2017  		wordsFracTo = digitsToWords(frac1 + frac2 + fracIncr)
  2018  		wordsIntTo, wordsFracTo, err = fixWordCntError(wordsIntTo, wordsFracTo)
  2019  		to.negative = from1.negative != from2.negative
  2020  		to.digitsInt = int8(wordsIntTo * digitsPerWord)
  2021  		to.digitsFrac = int8(wordsFracTo * digitsPerWord)
  2022  	}
  2023  	idxTo := 0
  2024  	stopTo := wordsIntTo + wordsFracTo
  2025  	if mod == nil {
  2026  		for digitsIntTo < 0 && idxTo < wordBufLen {
  2027  			to.wordBuf[idxTo] = 0
  2028  			idxTo++
  2029  			digitsIntTo++
  2030  		}
  2031  	}
  2032  	i = digitsToWords(prec1)
  2033  	len1 := i + digitsToWords(2*frac2+fracIncr+1) + 1
  2034  	if len1 < 3 {
  2035  		len1 = 3
  2036  	}
  2037  
  2038  	tmp1 := make([]int32, len1)
  2039  	copy(tmp1, from1.wordBuf[idx1:idx1+i])
  2040  
  2041  	start1 := 0
  2042  	var stop1 int
  2043  	start2 := idx2
  2044  	stop2 := idx2 + digitsToWords(prec2) - 1
  2045  
  2046  	/* removing end zeroes */
  2047  	for from2.wordBuf[stop2] == 0 && stop2 >= start2 {
  2048  		stop2--
  2049  	}
  2050  	len2 := stop2 - start2
  2051  	stop2++
  2052  
  2053  	/*
  2054  	   calculating norm2 (normalized from2.wordBuf[start2]) - we need from2.wordBuf[start2] to be large
  2055  	   (at least > DIG_BASE/2), but unlike Knuth's Alg. D we don't want to
  2056  	   normalize input numbers (as we don't make a copy of the divisor).
  2057  	   Thus we normalize first dec1 of buf2 only, and we'll normalize tmp1[start1]
  2058  	   on the fly for the purpose of guesstimation only.
  2059  	   It's also faster, as we're saving on normalization of from2.
  2060  	*/
  2061  	normFactor := wordBase / int64(from2.wordBuf[start2]+1)
  2062  	norm2 := int32(normFactor * int64(from2.wordBuf[start2]))
  2063  	if len2 > 0 {
  2064  		norm2 += int32(normFactor * int64(from2.wordBuf[start2+1]) / wordBase)
  2065  	}
  2066  	dcarry := int32(0)
  2067  	if tmp1[start1] < from2.wordBuf[start2] {
  2068  		dcarry = tmp1[start1]
  2069  		start1++
  2070  	}
  2071  
  2072  	// main loop
  2073  	var guess int64
  2074  	for ; idxTo < stopTo; idxTo++ {
  2075  		/* short-circuit, if possible */
  2076  		if dcarry == 0 && tmp1[start1] < from2.wordBuf[start2] {
  2077  			guess = 0
  2078  		} else {
  2079  			/* D3: make a guess */
  2080  			x := int64(tmp1[start1]) + int64(dcarry)*wordBase
  2081  			y := int64(tmp1[start1+1])
  2082  			guess = (normFactor*x + normFactor*y/wordBase) / int64(norm2)
  2083  			if guess >= wordBase {
  2084  				guess = wordBase - 1
  2085  			}
  2086  
  2087  			if len2 > 0 {
  2088  				/* remove normalization */
  2089  				if int64(from2.wordBuf[start2+1])*guess > (x-guess*int64(from2.wordBuf[start2]))*wordBase+y {
  2090  					guess--
  2091  				}
  2092  				if int64(from2.wordBuf[start2+1])*guess > (x-guess*int64(from2.wordBuf[start2]))*wordBase+y {
  2093  					guess--
  2094  				}
  2095  			}
  2096  
  2097  			/* D4: multiply and subtract */
  2098  			idx2 = stop2
  2099  			idx1 = start1 + len2
  2100  			var carry int32
  2101  			for carry = 0; idx2 > start2; idx1-- {
  2102  				var hi, lo int32
  2103  				idx2--
  2104  				x = guess * int64(from2.wordBuf[idx2])
  2105  				hi = int32(x / wordBase)
  2106  				lo = int32(x - int64(hi)*wordBase)
  2107  				tmp1[idx1], carry = sub2(tmp1[idx1], lo, carry)
  2108  				carry += hi
  2109  			}
  2110  			if dcarry < carry {
  2111  				carry = 1
  2112  			} else {
  2113  				carry = 0
  2114  			}
  2115  
  2116  			/* D5: check the remainder */
  2117  			if carry > 0 {
  2118  				/* D6: correct the guess */
  2119  				guess--
  2120  				idx2 = stop2
  2121  				idx1 = start1 + len2
  2122  				for carry = 0; idx2 > start2; idx1-- {
  2123  					idx2--
  2124  					tmp1[idx1], carry = add(tmp1[idx1], from2.wordBuf[idx2], carry)
  2125  				}
  2126  			}
  2127  		}
  2128  		if mod == nil {
  2129  			to.wordBuf[idxTo] = int32(guess)
  2130  		}
  2131  		dcarry = tmp1[start1]
  2132  		start1++
  2133  	}
  2134  	if mod != nil {
  2135  		/*
  2136  		   now the result is in tmp1, it has
  2137  		   digitsInt=prec1-frac1
  2138  		   digitsFrac=max(frac1, frac2)
  2139  		*/
  2140  		if dcarry != 0 {
  2141  			start1--
  2142  			tmp1[start1] = dcarry
  2143  		}
  2144  		idxTo = 0
  2145  
  2146  		digitsIntTo = prec1 - frac1 - start1*digitsPerWord
  2147  		if digitsIntTo < 0 {
  2148  			/* If leading zeroes in the fractional part were earlier stripped */
  2149  			wordsIntTo = digitsIntTo / digitsPerWord
  2150  		} else {
  2151  			wordsIntTo = digitsToWords(digitsIntTo)
  2152  		}
  2153  
  2154  		wordsFracTo = digitsToWords(int(to.digitsFrac))
  2155  		err = nil
  2156  		if wordsIntTo == 0 && wordsFracTo == 0 {
  2157  			*to = zeroMyDecimal
  2158  			return err
  2159  		}
  2160  		if wordsIntTo <= 0 {
  2161  			if -wordsIntTo >= wordBufLen {
  2162  				*to = zeroMyDecimal
  2163  				return ErrTruncated
  2164  			}
  2165  			stop1 = start1 + wordsIntTo + wordsFracTo
  2166  			wordsFracTo += wordsIntTo
  2167  			to.digitsInt = 0
  2168  			for wordsIntTo < 0 {
  2169  				to.wordBuf[idxTo] = 0
  2170  				idxTo++
  2171  				wordsIntTo++
  2172  			}
  2173  		} else {
  2174  			if wordsIntTo > wordBufLen {
  2175  				to.digitsInt = int8(digitsPerWord * wordBufLen)
  2176  				to.digitsFrac = 0
  2177  				return ErrOverflow
  2178  			}
  2179  			stop1 = start1 + wordsIntTo + wordsFracTo
  2180  			to.digitsInt = int8(myMin(wordsIntTo*digitsPerWord, int(from2.digitsInt)))
  2181  		}
  2182  		if wordsIntTo+wordsFracTo > wordBufLen {
  2183  			stop1 -= wordsIntTo + wordsFracTo - wordBufLen
  2184  			wordsFracTo = wordBufLen - wordsIntTo
  2185  			to.digitsFrac = int8(wordsFracTo * digitsPerWord)
  2186  			err = ErrTruncated
  2187  		}
  2188  		for start1 < stop1 {
  2189  			to.wordBuf[idxTo] = tmp1[start1]
  2190  			idxTo++
  2191  			start1++
  2192  		}
  2193  	}
  2194  	idxTo, digitsIntTo = to.removeLeadingZeros()
  2195  	to.digitsInt = int8(digitsIntTo)
  2196  	if idxTo != 0 {
  2197  		copy(to.wordBuf[:], to.wordBuf[idxTo:])
  2198  	}
  2199  	return err
  2200  }
  2201  
  2202  // DecimalPeak returns the length of the encoded decimal.
  2203  func DecimalPeak(b []byte) (int, error) {
  2204  	if len(b) < 3 {
  2205  		return 0, ErrBadNumber
  2206  	}
  2207  	precision := int(b[0])
  2208  	frac := int(b[1])
  2209  	return decimalBinSize(precision, frac) + 2, nil
  2210  }
  2211  
  2212  // NewDecFromInt creates a MyDecimal from int.
  2213  func NewDecFromInt(i int64) *MyDecimal {
  2214  	return new(MyDecimal).FromInt(i)
  2215  }
  2216  
  2217  // NewDecFromUint creates a MyDecimal from uint.
  2218  func NewDecFromUint(i uint64) *MyDecimal {
  2219  	return new(MyDecimal).FromUint(i)
  2220  }
  2221  
  2222  // NewDecFromFloatForTest creates a MyDecimal from float, as it returns no error, it should only be used in test.
  2223  func NewDecFromFloatForTest(f float64) *MyDecimal {
  2224  	dec := new(MyDecimal)
  2225  	err := dec.FromFloat64(f)
  2226  	terror.Log(errors.Trace(err))
  2227  	return dec
  2228  }
  2229  
  2230  // NewDecFromStringForTest creates a MyDecimal from string, as it returns no error, it should only be used in test.
  2231  func NewDecFromStringForTest(s string) *MyDecimal {
  2232  	dec := new(MyDecimal)
  2233  	err := dec.FromString([]byte(s))
  2234  	terror.Log(errors.Trace(err))
  2235  	return dec
  2236  }
  2237  
  2238  // NewMaxOrMinDec returns the max or min value decimal for given precision and fraction.
  2239  func NewMaxOrMinDec(negative bool, prec, frac int) *MyDecimal {
  2240  	str := make([]byte, prec+2)
  2241  	for i := 0; i < len(str); i++ {
  2242  		str[i] = '9'
  2243  	}
  2244  	if negative {
  2245  		str[0] = '-'
  2246  	} else {
  2247  		str[0] = '+'
  2248  	}
  2249  	str[1+prec-frac] = '.'
  2250  	dec := new(MyDecimal)
  2251  	err := dec.FromString(str)
  2252  	terror.Log(errors.Trace(err))
  2253  	return dec
  2254  }