github.com/dubbogo/gost@v1.14.0/math/big/decimal.go (about)

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