github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/mysql/decimal.go (about)

     1  // The MIT License (MIT)
     2  
     3  // Copyright (c) 2015 Spring, Inc.
     4  
     5  // Permission is hereby granted, free of charge, to any person obtaining a copy
     6  // of this software and associated documentation files (the "Software"), to deal
     7  // in the Software without restriction, including without limitation the rights
     8  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     9  // copies of the Software, and to permit persons to whom the Software is
    10  // furnished to do so, subject to the following conditions:
    11  
    12  // The above copyright notice and this permission notice shall be included in
    13  // all copies or substantial portions of the Software.
    14  
    15  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    16  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    17  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    18  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    19  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    20  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    21  // THE SOFTWARE.
    22  
    23  // - Based on https://yougam/libraries/oguzbilgic/fpd, which has the following license:
    24  // """
    25  // The MIT License (MIT)
    26  
    27  // Copyright (c) 2013 Oguz Bilgic
    28  
    29  // Permission is hereby granted, free of charge, to any person obtaining a copy of
    30  // this software and associated documentation files (the "Software"), to deal in
    31  // the Software without restriction, including without limitation the rights to
    32  // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
    33  // the Software, and to permit persons to whom the Software is furnished to do so,
    34  // subject to the following conditions:
    35  
    36  // The above copyright notice and this permission notice shall be included in all
    37  // copies or substantial portions of the Software.
    38  
    39  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    40  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
    41  // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
    42  // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
    43  // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    44  // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    45  // """
    46  
    47  // Copyright 2015 PingCAP, Inc.
    48  //
    49  // Licensed under the Apache License, Version 2.0 (the "License");
    50  // you may not use this file except in compliance with the License.
    51  // You may obtain a copy of the License at
    52  //
    53  //     http://www.apache.org/licenses/LICENSE-2.0
    54  //
    55  // Unless required by applicable law or agreed to in writing, software
    56  // distributed under the License is distributed on an "AS IS" BASIS,
    57  // See the License for the specific language governing permissions and
    58  // limitations under the License.
    59  
    60  package mysql
    61  
    62  // Decimal implements an arbitrary precision fixed-point decimal.
    63  //
    64  // To use as part of a struct:
    65  //
    66  //     type Struct struct {
    67  //         Number Decimal
    68  //     }
    69  //
    70  // The zero-value of a Decimal is 0, as you would expect.
    71  //
    72  // The best way to create a new Decimal is to use decimal.NewFromString, ex:
    73  //
    74  //     n, err := decimal.NewFromString("-123.4567")
    75  //     n.String() // output: "-123.4567"
    76  //
    77  // NOTE: this can "only" represent numbers with a maximum of 2^31 digits
    78  // after the decimal point.
    79  
    80  import (
    81  	"database/sql/driver"
    82  	"fmt"
    83  	"math"
    84  	"math/big"
    85  	"strconv"
    86  	"strings"
    87  )
    88  
    89  // DivisionPrecision is the number of decimal places in the result when it
    90  // doesn't divide exactly.
    91  //
    92  // Example:
    93  //
    94  //     d1 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(3)
    95  //     d1.String() // output: "0.6667"
    96  //     d2 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(30000)
    97  //     d2.String() // output: "0.0001"
    98  //     d3 := decimal.NewFromFloat(20000).Div(decimal.NewFromFloat(3)
    99  //     d3.String() // output: "6666.6666666666666667"
   100  //     decimal.DivisionPrecision = 3
   101  //     d4 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(3)
   102  //     d4.String() // output: "0.6667"
   103  //
   104  const (
   105  	MaxFractionDigits    = 30
   106  	DivIncreasePrecision = 4
   107  )
   108  
   109  // ZeroDecimal is zero constant, to make computations faster.
   110  var ZeroDecimal = NewDecimalFromInt(0, 1)
   111  
   112  var zeroInt = big.NewInt(0)
   113  var oneInt = big.NewInt(1)
   114  var fiveInt = big.NewInt(5)
   115  var tenInt = big.NewInt(10)
   116  
   117  // Decimal represents a fixed-point decimal. It is immutable.
   118  // number = value * 10 ^ exp
   119  type Decimal struct {
   120  	value *big.Int
   121  
   122  	// this must be an int32, because we cast it to float64 during
   123  	// calculations. If exp is 64 bit, we might lose precision.
   124  	// If we cared about being able to represent every possible decimal, we
   125  	// could make exp a *big.Int but it would hurt performance and numbers
   126  	// like that are unrealistic.
   127  	exp        int32
   128  	fracDigits int32 // Number of fractional digits for string result.
   129  }
   130  
   131  // ConvertToDecimal converts interface to decimal.
   132  func ConvertToDecimal(value interface{}) (Decimal, error) {
   133  	switch v := value.(type) {
   134  	case int8:
   135  		return NewDecimalFromInt(int64(v), 0), nil
   136  	case int16:
   137  		return NewDecimalFromInt(int64(v), 0), nil
   138  	case int32:
   139  		return NewDecimalFromInt(int64(v), 0), nil
   140  	case int64:
   141  		return NewDecimalFromInt(int64(v), 0), nil
   142  	case int:
   143  		return NewDecimalFromInt(int64(v), 0), nil
   144  	case uint8:
   145  		return NewDecimalFromUint(uint64(v), 0), nil
   146  	case uint16:
   147  		return NewDecimalFromUint(uint64(v), 0), nil
   148  	case uint32:
   149  		return NewDecimalFromUint(uint64(v), 0), nil
   150  	case uint64:
   151  		return NewDecimalFromUint(uint64(v), 0), nil
   152  	case uint:
   153  		return NewDecimalFromUint(uint64(v), 0), nil
   154  	case float32:
   155  		return NewDecimalFromFloat(float64(v)), nil
   156  	case float64:
   157  		return NewDecimalFromFloat(float64(v)), nil
   158  	case string:
   159  		return ParseDecimal(v)
   160  	case Decimal:
   161  		return v, nil
   162  	case Hex:
   163  		return NewDecimalFromInt(int64(v.Value), 0), nil
   164  	case Bit:
   165  		return NewDecimalFromUint(uint64(v.Value), 0), nil
   166  	case Enum:
   167  		return NewDecimalFromUint(uint64(v.Value), 0), nil
   168  	case Set:
   169  		return NewDecimalFromUint(uint64(v.Value), 0), nil
   170  	default:
   171  		return Decimal{}, fmt.Errorf("can't convert %v to decimal", value)
   172  	}
   173  }
   174  
   175  // NewDecimalFromInt returns a new fixed-point decimal, value * 10 ^ exp.
   176  func NewDecimalFromInt(value int64, exp int32) Decimal {
   177  	return Decimal{
   178  		value:      big.NewInt(value),
   179  		exp:        exp,
   180  		fracDigits: fracDigitsDefault(exp),
   181  	}
   182  }
   183  
   184  // NewDecimalFromUint returns a new fixed-point decimal, value * 10 ^ exp.
   185  func NewDecimalFromUint(value uint64, exp int32) Decimal {
   186  	return Decimal{
   187  		value:      big.NewInt(0).SetUint64(value),
   188  		exp:        exp,
   189  		fracDigits: fracDigitsDefault(exp),
   190  	}
   191  }
   192  
   193  // ParseDecimal returns a new Decimal from a string representation.
   194  //
   195  // Example:
   196  //
   197  //     d, err := ParseDecimal("-123.45")
   198  //     d2, err := ParseDecimal(".0001")
   199  //
   200  func ParseDecimal(value string) (Decimal, error) {
   201  	var intString string
   202  	var exp = int32(0)
   203  
   204  	n := strings.IndexAny(value, "eE")
   205  	if n > 0 {
   206  		// It is scientific notation, like 3.14e10
   207  		expInt, err := strconv.Atoi(value[n+1:])
   208  		if err != nil {
   209  			return Decimal{}, fmt.Errorf("can't convert %s to decimal, incorrect exponent", value)
   210  		}
   211  		value = value[0:n]
   212  		exp = int32(expInt)
   213  	}
   214  
   215  	parts := strings.Split(value, ".")
   216  	if len(parts) == 1 {
   217  		// There is no decimal point, we can just parse the original string as
   218  		// an int.
   219  		intString = value
   220  	} else if len(parts) == 2 {
   221  		intString = parts[0] + parts[1]
   222  		expInt := -len(parts[1])
   223  		exp += int32(expInt)
   224  	} else {
   225  		return Decimal{}, fmt.Errorf("can't convert %s to decimal: too many .s", value)
   226  	}
   227  
   228  	dValue := new(big.Int)
   229  	_, ok := dValue.SetString(intString, 10)
   230  	if !ok {
   231  		return Decimal{}, fmt.Errorf("can't convert %s to decimal", value)
   232  	}
   233  
   234  	val := Decimal{
   235  		value:      dValue,
   236  		exp:        exp,
   237  		fracDigits: fracDigitsDefault(exp),
   238  	}
   239  	if exp < -MaxFractionDigits {
   240  		val = val.rescale(-MaxFractionDigits)
   241  	}
   242  	return val, nil
   243  }
   244  
   245  // NewDecimalFromFloat converts a float64 to Decimal.
   246  //
   247  // Example:
   248  //
   249  //     NewDecimalFromFloat(123.45678901234567).String() // output: "123.4567890123456"
   250  //     NewDecimalFromFloat(.00000000000000001).String() // output: "0.00000000000000001"
   251  //
   252  // NOTE: this will panic on NaN, +/-inf.
   253  func NewDecimalFromFloat(value float64) Decimal {
   254  	floor := math.Floor(value)
   255  
   256  	// fast path, where float is an int.
   257  	if floor == value && !math.IsInf(value, 0) {
   258  		return NewDecimalFromInt(int64(value), 0)
   259  	}
   260  
   261  	str := strconv.FormatFloat(value, 'f', -1, 64)
   262  	dec, err := ParseDecimal(str)
   263  	if err != nil {
   264  		panic(err)
   265  	}
   266  	return dec
   267  }
   268  
   269  // NewDecimalFromFloatWithExponent converts a float64 to Decimal, with an arbitrary
   270  // number of fractional digits.
   271  //
   272  // Example:
   273  //
   274  //     NewDecimalFromFloatWithExponent(123.456, -2).String() // output: "123.46"
   275  //
   276  func NewDecimalFromFloatWithExponent(value float64, exp int32) Decimal {
   277  	mul := math.Pow(10, -float64(exp))
   278  	floatValue := value * mul
   279  	if math.IsNaN(floatValue) || math.IsInf(floatValue, 0) {
   280  		panic(fmt.Sprintf("Cannot create a Decimal from %v", floatValue))
   281  	}
   282  	dValue := big.NewInt(round(floatValue))
   283  
   284  	return Decimal{
   285  		value:      dValue,
   286  		exp:        exp,
   287  		fracDigits: fracDigitsDefault(exp),
   288  	}
   289  }
   290  
   291  // rescale returns a rescaled version of the decimal. Returned
   292  // decimal may be less precise if the given exponent is bigger
   293  // than the initial exponent of the Decimal.
   294  // NOTE: this will truncate, NOT round
   295  //
   296  // Example:
   297  //
   298  // 	d := New(12345, -4)
   299  //	d2 := d.rescale(-1)
   300  //	d3 := d2.rescale(-4)
   301  //	println(d1)
   302  //	println(d2)
   303  //	println(d3)
   304  //
   305  // Output:
   306  //
   307  //	1.2345
   308  //	1.2
   309  //	1.2000
   310  //
   311  func (d Decimal) rescale(exp int32) Decimal {
   312  	d.ensureInitialized()
   313  	if exp < -MaxFractionDigits-1 {
   314  		// Limit the number of digits but we can not call Round here because it is called by Round.
   315  		// Limit it to MaxFractionDigits + 1 to make sure the final result is correct.
   316  		exp = -MaxFractionDigits - 1
   317  	}
   318  	// Must convert exps to float64 before - to prevent overflow.
   319  	diff := math.Abs(float64(exp) - float64(d.exp))
   320  	value := new(big.Int).Set(d.value)
   321  
   322  	expScale := new(big.Int).Exp(tenInt, big.NewInt(int64(diff)), nil)
   323  	if exp > d.exp {
   324  		value = value.Quo(value, expScale)
   325  	} else if exp < d.exp {
   326  		value = value.Mul(value, expScale)
   327  	}
   328  	return Decimal{
   329  		value:      value,
   330  		exp:        exp,
   331  		fracDigits: d.fracDigits,
   332  	}
   333  }
   334  
   335  // Abs returns the absolute value of the decimal.
   336  func (d Decimal) Abs() Decimal {
   337  	d.ensureInitialized()
   338  	d2Value := new(big.Int).Abs(d.value)
   339  	return Decimal{
   340  		value:      d2Value,
   341  		exp:        d.exp,
   342  		fracDigits: d.fracDigits,
   343  	}
   344  }
   345  
   346  // Add returns d + d2.
   347  func (d Decimal) Add(d2 Decimal) Decimal {
   348  	baseExp := min(d.exp, d2.exp)
   349  	rd := d.rescale(baseExp)
   350  	rd2 := d2.rescale(baseExp)
   351  
   352  	d3Value := new(big.Int).Add(rd.value, rd2.value)
   353  	return Decimal{
   354  		value:      d3Value,
   355  		exp:        baseExp,
   356  		fracDigits: fracDigitsPlus(d.fracDigits, d2.fracDigits),
   357  	}
   358  }
   359  
   360  // Sub returns d - d2.
   361  func (d Decimal) Sub(d2 Decimal) Decimal {
   362  	baseExp := min(d.exp, d2.exp)
   363  	rd := d.rescale(baseExp)
   364  	rd2 := d2.rescale(baseExp)
   365  
   366  	d3Value := new(big.Int).Sub(rd.value, rd2.value)
   367  	return Decimal{
   368  		value:      d3Value,
   369  		exp:        baseExp,
   370  		fracDigits: fracDigitsPlus(d.fracDigits, d2.fracDigits),
   371  	}
   372  }
   373  
   374  // Mul returns d * d2.
   375  func (d Decimal) Mul(d2 Decimal) Decimal {
   376  	d.ensureInitialized()
   377  	d2.ensureInitialized()
   378  
   379  	expInt64 := int64(d.exp) + int64(d2.exp)
   380  	if expInt64 > math.MaxInt32 || expInt64 < math.MinInt32 {
   381  		// It is better to panic than to give incorrect results, as
   382  		// decimals are usually used for money.
   383  		panic(fmt.Sprintf("exponent %v overflows an int32!", expInt64))
   384  	}
   385  
   386  	d3Value := new(big.Int).Mul(d.value, d2.value)
   387  	val := Decimal{
   388  		value:      d3Value,
   389  		exp:        int32(expInt64),
   390  		fracDigits: fracDigitsMul(d.fracDigits, d2.fracDigits),
   391  	}
   392  	if val.exp < -(MaxFractionDigits) {
   393  		val = val.Round(MaxFractionDigits)
   394  	}
   395  	return val
   396  }
   397  
   398  // Div returns d / d2. If it doesn't divide exactly, the result will have
   399  // DivisionPrecision digits after the decimal point.
   400  func (d Decimal) Div(d2 Decimal) Decimal {
   401  	// Division is hard, use Rat to do it.
   402  	ratNum := d.Rat()
   403  	ratDenom := d2.Rat()
   404  
   405  	quoRat := big.NewRat(0, 1).Quo(ratNum, ratDenom)
   406  
   407  	// Converting from Rat to Decimal inefficiently for now.
   408  	ret, err := ParseDecimal(quoRat.FloatString(MaxFractionDigits + 1))
   409  	if err != nil {
   410  		panic(err) // This should never happen.
   411  	}
   412  	// To pass test "2 / 3 * 3 < 2" -> "1".
   413  	ret = ret.Truncate(MaxFractionDigits)
   414  	ret.fracDigits = fracDigitsDiv(d.fracDigits)
   415  	return ret
   416  }
   417  
   418  // Cmp compares the numbers represented by d and d2, and returns:
   419  //
   420  //     -1 if d <  d2
   421  //      0 if d == d2
   422  //     +1 if d >  d2
   423  //
   424  func (d Decimal) Cmp(d2 Decimal) int {
   425  	baseExp := min(d.exp, d2.exp)
   426  	rd := d.rescale(baseExp)
   427  	rd2 := d2.rescale(baseExp)
   428  
   429  	return rd.value.Cmp(rd2.value)
   430  }
   431  
   432  // Equals returns whether the numbers represented by d and d2 are equal.
   433  func (d Decimal) Equals(d2 Decimal) bool {
   434  	return d.Cmp(d2) == 0
   435  }
   436  
   437  // Exponent returns the exponent, or scale component of the decimal.
   438  func (d Decimal) Exponent() int32 {
   439  	return d.exp
   440  }
   441  
   442  // FracDigits returns the number of fractional digits of the decimal.
   443  func (d Decimal) FracDigits() int32 {
   444  	return d.fracDigits
   445  }
   446  
   447  // IntPart returns the integer component of the decimal.
   448  func (d Decimal) IntPart() int64 {
   449  	scaledD := d.rescale(0)
   450  	return scaledD.value.Int64()
   451  }
   452  
   453  // Rat returns a rational number representation of the decimal.
   454  func (d Decimal) Rat() *big.Rat {
   455  	d.ensureInitialized()
   456  	if d.exp <= 0 {
   457  		// It must negate after casting to prevent int32 overflow.
   458  		denom := new(big.Int).Exp(tenInt, big.NewInt(-int64(d.exp)), nil)
   459  		return new(big.Rat).SetFrac(d.value, denom)
   460  	}
   461  
   462  	mul := new(big.Int).Exp(tenInt, big.NewInt(int64(d.exp)), nil)
   463  	num := new(big.Int).Mul(d.value, mul)
   464  	return new(big.Rat).SetFrac(num, oneInt)
   465  }
   466  
   467  // Float64 returns the nearest float64 value for d and a bool indicating
   468  // whether f represents d exactly.
   469  // For more details, see the documentation for big.Rat.Float64.
   470  func (d Decimal) Float64() (f float64, exact bool) {
   471  	return d.Rat().Float64()
   472  }
   473  
   474  // String returns the string representation of the decimal
   475  // with the fixed point.
   476  //
   477  // Example:
   478  //
   479  //     d := New(-12345, -3)
   480  //     println(d.String())
   481  //
   482  // Output:
   483  //
   484  //     -12.345
   485  //
   486  func (d Decimal) String() string {
   487  	return d.StringFixed(d.fracDigits)
   488  }
   489  
   490  // StringFixed returns a rounded fixed-point string with places digits after
   491  // the decimal point.
   492  //
   493  // Example:
   494  //
   495  // 	   NewFromFloat(0).StringFixed(2) // output: "0.00"
   496  // 	   NewFromFloat(0).StringFixed(0) // output: "0"
   497  // 	   NewFromFloat(5.45).StringFixed(0) // output: "5"
   498  // 	   NewFromFloat(5.45).StringFixed(1) // output: "5.5"
   499  // 	   NewFromFloat(5.45).StringFixed(2) // output: "5.45"
   500  // 	   NewFromFloat(5.45).StringFixed(3) // output: "5.450"
   501  // 	   NewFromFloat(545).StringFixed(-1) // output: "550"
   502  //
   503  func (d Decimal) StringFixed(places int32) string {
   504  	rounded := d.Round(places)
   505  	return rounded.string(false)
   506  }
   507  
   508  // Round rounds the decimal to places decimal places.
   509  // If places < 0, it will round the integer part to the nearest 10^(-places).
   510  //
   511  // Example:
   512  //
   513  // 	   NewFromFloat(5.45).Round(1).String() // output: "5.5"
   514  // 	   NewFromFloat(545).Round(-1).String() // output: "550"
   515  //
   516  func (d Decimal) Round(places int32) Decimal {
   517  	// Truncate to places + 1.
   518  	ret := d.rescale(-places - 1)
   519  
   520  	// Add sign(d) * 0.5.
   521  	if ret.value.Sign() < 0 {
   522  		ret.value.Sub(ret.value, fiveInt)
   523  	} else {
   524  		ret.value.Add(ret.value, fiveInt)
   525  	}
   526  
   527  	// Floor for positive numbers, Ceil for negative numbers.
   528  	_, m := ret.value.DivMod(ret.value, tenInt, new(big.Int))
   529  	ret.exp++
   530  	if ret.value.Sign() < 0 && m.Cmp(zeroInt) != 0 {
   531  		ret.value.Add(ret.value, oneInt)
   532  	}
   533  	ret.fracDigits = places
   534  	return ret
   535  }
   536  
   537  // Floor returns the nearest integer value less than or equal to d.
   538  func (d Decimal) Floor() Decimal {
   539  	d.ensureInitialized()
   540  
   541  	exp := big.NewInt(10)
   542  
   543  	// It must negate after casting to prevent int32 overflow.
   544  	exp.Exp(exp, big.NewInt(-int64(d.exp)), nil)
   545  
   546  	z := new(big.Int).Div(d.value, exp)
   547  	return Decimal{value: z, exp: 0}
   548  }
   549  
   550  // Ceil returns the nearest integer value greater than or equal to d.
   551  func (d Decimal) Ceil() Decimal {
   552  	d.ensureInitialized()
   553  
   554  	exp := big.NewInt(10)
   555  
   556  	// It must negate after casting to prevent int32 overflow.
   557  	exp.Exp(exp, big.NewInt(-int64(d.exp)), nil)
   558  
   559  	z, m := new(big.Int).DivMod(d.value, exp, new(big.Int))
   560  	if m.Cmp(zeroInt) != 0 {
   561  		z.Add(z, oneInt)
   562  	}
   563  	return Decimal{value: z, exp: 0}
   564  }
   565  
   566  // Truncate truncates off digits from the number, without rounding.
   567  //
   568  // NOTE: precision is the last digit that will not be truncated (must be >= 0).
   569  //
   570  // Example:
   571  //
   572  //     decimal.NewFromString("123.456").Truncate(2).String() // "123.45"
   573  //
   574  func (d Decimal) Truncate(precision int32) Decimal {
   575  	d.ensureInitialized()
   576  	if precision >= 0 && -precision > d.exp {
   577  		d = d.rescale(-precision)
   578  	}
   579  	d.fracDigits = precision
   580  	return d
   581  }
   582  
   583  // UnmarshalJSON implements the json.Unmarshaler interface.
   584  func (d *Decimal) UnmarshalJSON(decimalBytes []byte) error {
   585  	str, err := unquoteIfQuoted(decimalBytes)
   586  	if err != nil {
   587  		return fmt.Errorf("Error decoding string '%s': %s", decimalBytes, err)
   588  	}
   589  
   590  	decimal, err := ParseDecimal(str)
   591  	*d = decimal
   592  	if err != nil {
   593  		return fmt.Errorf("Error decoding string '%s': %s", str, err)
   594  	}
   595  	return nil
   596  }
   597  
   598  // MarshalJSON implements the json.Marshaler interface.
   599  func (d Decimal) MarshalJSON() ([]byte, error) {
   600  	str := "\"" + d.String() + "\""
   601  	return []byte(str), nil
   602  }
   603  
   604  // Scan implements the sql.Scanner interface for database deserialization.
   605  func (d *Decimal) Scan(value interface{}) error {
   606  	str, err := unquoteIfQuoted(value)
   607  	if err != nil {
   608  		return err
   609  	}
   610  	*d, err = ParseDecimal(str)
   611  
   612  	return err
   613  }
   614  
   615  // Value implements the driver.Valuer interface for database serialization.
   616  func (d Decimal) Value() (driver.Value, error) {
   617  	return d.String(), nil
   618  }
   619  
   620  // BigIntValue returns the *bit.Int value member of decimal.
   621  func (d Decimal) BigIntValue() *big.Int {
   622  	return d.value
   623  }
   624  
   625  // UnmarshalText implements the encoding.TextUnmarshaler interface for XML
   626  // deserialization.
   627  func (d *Decimal) UnmarshalText(text []byte) error {
   628  	str := string(text)
   629  
   630  	dec, err := ParseDecimal(str)
   631  	*d = dec
   632  	if err != nil {
   633  		return fmt.Errorf("Error decoding string '%s': %s", str, err)
   634  	}
   635  
   636  	return nil
   637  }
   638  
   639  // MarshalText implements the encoding.TextMarshaler interface for XML
   640  // serialization.
   641  func (d Decimal) MarshalText() (text []byte, err error) {
   642  	return []byte(d.String()), nil
   643  }
   644  
   645  // StringScaled first scales the decimal then calls .String() on it.
   646  // NOTE: buggy, unintuitive, and DEPRECATED! Use StringFixed instead.
   647  func (d Decimal) StringScaled(exp int32) string {
   648  	return d.rescale(exp).String()
   649  }
   650  
   651  func (d Decimal) string(trimTrailingZeros bool) string {
   652  	if d.exp >= 0 {
   653  		return d.rescale(0).value.String()
   654  	}
   655  
   656  	abs := new(big.Int).Abs(d.value)
   657  	str := abs.String()
   658  
   659  	var intPart, fractionalPart string
   660  
   661  	// this cast to int will cause bugs if d.exp == INT_MIN
   662  	// and you are on a 32-bit machine. Won't fix this super-edge case.
   663  	dExpInt := int(d.exp)
   664  	if len(str) > -dExpInt {
   665  		intPart = str[:len(str)+dExpInt]
   666  		fractionalPart = str[len(str)+dExpInt:]
   667  	} else {
   668  		intPart = "0"
   669  
   670  		num0s := -dExpInt - len(str)
   671  		fractionalPart = strings.Repeat("0", num0s) + str
   672  	}
   673  
   674  	if trimTrailingZeros {
   675  		i := len(fractionalPart) - 1
   676  		for ; i >= 0; i-- {
   677  			if fractionalPart[i] != '0' {
   678  				break
   679  			}
   680  		}
   681  		fractionalPart = fractionalPart[:i+1]
   682  	}
   683  
   684  	number := intPart
   685  	if len(fractionalPart) > 0 {
   686  		number += "." + fractionalPart
   687  	}
   688  
   689  	if d.value.Sign() < 0 {
   690  		return "-" + number
   691  	}
   692  
   693  	return number
   694  }
   695  
   696  func (d *Decimal) ensureInitialized() {
   697  	if d.value == nil {
   698  		d.value = new(big.Int)
   699  	}
   700  }
   701  
   702  func min(x, y int32) int32 {
   703  	if x >= y {
   704  		return y
   705  	}
   706  	return x
   707  }
   708  
   709  func max(x, y int32) int32 {
   710  	if x >= y {
   711  		return x
   712  	}
   713  	return y
   714  }
   715  
   716  func round(n float64) int64 {
   717  	if n < 0 {
   718  		return int64(n - 0.5)
   719  	}
   720  	return int64(n + 0.5)
   721  }
   722  
   723  func unquoteIfQuoted(value interface{}) (string, error) {
   724  	bytes, ok := value.([]byte)
   725  	if !ok {
   726  		return "", fmt.Errorf("Could not convert value '%+v' to byte array",
   727  			value)
   728  	}
   729  
   730  	// If the amount is quoted, strip the quotes.
   731  	if len(bytes) > 2 && bytes[0] == '"' && bytes[len(bytes)-1] == '"' {
   732  		bytes = bytes[1 : len(bytes)-1]
   733  	}
   734  	return string(bytes), nil
   735  }
   736  
   737  func fracDigitsDefault(exp int32) int32 {
   738  	if exp < 0 {
   739  		return min(MaxFractionDigits, -exp)
   740  	}
   741  
   742  	return 0
   743  }
   744  
   745  func fracDigitsPlus(x, y int32) int32 {
   746  	return max(x, y)
   747  }
   748  
   749  func fracDigitsDiv(x int32) int32 {
   750  	return min(x+DivIncreasePrecision, MaxFractionDigits)
   751  }
   752  
   753  func fracDigitsMul(a, b int32) int32 {
   754  	return min(MaxFractionDigits, a+b)
   755  }