github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/types/decimal.go (about)

     1  package types
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"math/big"
     8  	"strconv"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/tendermint/go-amino"
    13  )
    14  
    15  // NOTE: never use new(Dec) or else we will panic unmarshalling into the
    16  // nil embedded big.Int
    17  type Dec struct {
    18  	*big.Int `json:"int"`
    19  }
    20  
    21  const (
    22  	// number of decimal places
    23  	Precision = 18
    24  
    25  	// bytes required to represent the above precision
    26  	// Ceiling[Log2[999 999 999 999 999 999]]
    27  	DecimalPrecisionBits = 60
    28  
    29  	// max number of iterations in ApproxRoot function
    30  	maxApproxRootIterations = 100
    31  )
    32  
    33  var (
    34  	precisionReuse       = new(big.Int).Exp(big.NewInt(10), big.NewInt(Precision), nil)
    35  	fivePrecision        = new(big.Int).Quo(precisionReuse, big.NewInt(2))
    36  	precisionMultipliers []*big.Int
    37  	zeroInt              = big.NewInt(0)
    38  	oneInt               = big.NewInt(1)
    39  	tenInt               = big.NewInt(10)
    40  )
    41  
    42  // Decimal errors
    43  var (
    44  	ErrEmptyDecimalStr      = errors.New("decimal string cannot be empty")
    45  	ErrInvalidDecimalLength = errors.New("invalid decimal length")
    46  	ErrInvalidDecimalStr    = errors.New("invalid decimal string")
    47  )
    48  
    49  // Set precision multipliers
    50  func init() {
    51  	precisionMultipliers = make([]*big.Int, Precision+1)
    52  	for i := 0; i <= Precision; i++ {
    53  		precisionMultipliers[i] = calcPrecisionMultiplier(int64(i))
    54  	}
    55  }
    56  
    57  func precisionInt() *big.Int {
    58  	return new(big.Int).Set(precisionReuse)
    59  }
    60  
    61  func ZeroDec() Dec     { return Dec{new(big.Int).Set(zeroInt)} }
    62  func OneDec() Dec      { return Dec{precisionInt()} }
    63  func SmallestDec() Dec { return Dec{new(big.Int).Set(oneInt)} }
    64  
    65  // calculate the precision multiplier
    66  func calcPrecisionMultiplier(prec int64) *big.Int {
    67  	if prec > Precision {
    68  		panic(fmt.Sprintf("too much precision, maximum %v, provided %v", Precision, prec))
    69  	}
    70  	zerosToAdd := Precision - prec
    71  	multiplier := new(big.Int).Exp(tenInt, big.NewInt(zerosToAdd), nil)
    72  	return multiplier
    73  }
    74  
    75  // get the precision multiplier, do not mutate result
    76  func precisionMultiplier(prec int64) *big.Int {
    77  	if prec > Precision {
    78  		panic(fmt.Sprintf("too much precision, maximum %v, provided %v", Precision, prec))
    79  	}
    80  	return precisionMultipliers[prec]
    81  }
    82  
    83  //______________________________________________________________________________________________
    84  
    85  // create a new Dec from integer assuming whole number
    86  func NewDec(i int64) Dec {
    87  	return NewDecWithPrec(i, 0)
    88  }
    89  
    90  // create a new Dec from integer with decimal place at prec
    91  // CONTRACT: prec <= Precision
    92  func NewDecWithPrec(i, prec int64) Dec {
    93  	return Dec{
    94  		new(big.Int).Mul(big.NewInt(i), precisionMultiplier(prec)),
    95  	}
    96  }
    97  
    98  // create a new Dec from big integer assuming whole numbers
    99  // CONTRACT: prec <= Precision
   100  func NewDecFromBigInt(i *big.Int) Dec {
   101  	return NewDecFromBigIntWithPrec(i, 0)
   102  }
   103  
   104  // create a new Dec from big integer assuming whole numbers
   105  // CONTRACT: prec <= Precision
   106  func NewDecFromBigIntWithPrec(i *big.Int, prec int64) Dec {
   107  	return Dec{
   108  		new(big.Int).Mul(i, precisionMultiplier(prec)),
   109  	}
   110  }
   111  
   112  // NewDecWithBigIntAndPrec create a new Dec from big integer assuming whole numbers
   113  // CONTRACT: prec <= Precision
   114  // The new Dec takes ownership of i, and the
   115  // caller should not use i after this call
   116  func NewDecWithBigIntAndPrec(i *big.Int, prec int64) Dec {
   117  	return Dec{
   118  		i.Mul(i, precisionMultiplier(prec)),
   119  	}
   120  }
   121  
   122  // create a new Dec from big integer assuming whole numbers
   123  // CONTRACT: prec <= Precision
   124  func NewDecFromInt(i Int) Dec {
   125  	return NewDecFromIntWithPrec(i, 0)
   126  }
   127  
   128  // create a new Dec from big integer with decimal place at prec
   129  // CONTRACT: prec <= Precision
   130  func NewDecFromIntWithPrec(i Int, prec int64) Dec {
   131  	return Dec{
   132  		new(big.Int).Mul(i.BigInt(), precisionMultiplier(prec)),
   133  	}
   134  }
   135  
   136  // create a decimal from an input decimal string.
   137  // valid must come in the form:
   138  //   (-) whole integers (.) decimal integers
   139  // examples of acceptable input include:
   140  //   -123.456
   141  //   456.7890
   142  //   345
   143  //   -456789
   144  //
   145  // NOTE - An error will return if more decimal places
   146  // are provided in the string than the constant Precision.
   147  //
   148  // CONTRACT - This function does not mutate the input str.
   149  func NewDecFromStr(str string) (Dec, error) {
   150  	if len(str) == 0 {
   151  		return Dec{}, ErrEmptyDecimalStr
   152  	}
   153  
   154  	// first extract any negative symbol
   155  	neg := false
   156  	if str[0] == '-' {
   157  		neg = true
   158  		str = str[1:]
   159  	}
   160  
   161  	if len(str) == 0 {
   162  		return Dec{}, ErrEmptyDecimalStr
   163  	}
   164  
   165  	strs := strings.Split(str, ".")
   166  	lenDecs := 0
   167  	combinedStr := strs[0]
   168  
   169  	if len(strs) == 2 { // has a decimal place
   170  		lenDecs = len(strs[1])
   171  		if lenDecs == 0 || len(combinedStr) == 0 {
   172  			return Dec{}, ErrInvalidDecimalLength
   173  		}
   174  		combinedStr += strs[1]
   175  
   176  	} else if len(strs) > 2 {
   177  		return Dec{}, ErrInvalidDecimalStr
   178  	}
   179  
   180  	if lenDecs > Precision {
   181  		return Dec{}, fmt.Errorf("invalid precision; max: %d, got: %d", Precision, lenDecs)
   182  	}
   183  
   184  	// add some extra zero's to correct to the Precision factor
   185  	zerosToAdd := Precision - lenDecs
   186  	zeros := fmt.Sprintf(`%0`+strconv.Itoa(zerosToAdd)+`s`, "")
   187  	combinedStr += zeros
   188  
   189  	combined, ok := new(big.Int).SetString(combinedStr, 10) // base 10
   190  	if !ok {
   191  		return Dec{}, fmt.Errorf("failed to set decimal string: %s", combinedStr)
   192  	}
   193  	if combined.BitLen() > maxBitLen {
   194  		return Dec{}, fmt.Errorf("decimal out of range; bitLen: got %d, max %d", combined.BitLen(), maxBitLen)
   195  	}
   196  	if neg {
   197  		combined = new(big.Int).Neg(combined)
   198  	}
   199  
   200  	return Dec{combined}, nil
   201  }
   202  
   203  // Decimal from string, panic on error
   204  func MustNewDecFromStr(s string) Dec {
   205  	dec, err := NewDecFromStr(s)
   206  	if err != nil {
   207  		panic(err)
   208  	}
   209  	return dec
   210  }
   211  
   212  //______________________________________________________________________________________________
   213  //nolint
   214  func (d Dec) IsNil() bool       { return d.Int == nil }                 // is decimal nil
   215  func (d Dec) IsZero() bool      { return (d.Int).Sign() == 0 }          // is equal to zero
   216  func (d Dec) IsNegative() bool  { return (d.Int).Sign() == -1 }         // is negative
   217  func (d Dec) IsPositive() bool  { return (d.Int).Sign() == 1 }          // is positive
   218  func (d Dec) Equal(d2 Dec) bool { return (d.Int).Cmp(d2.Int) == 0 }     // equal decimals
   219  func (d Dec) GT(d2 Dec) bool    { return (d.Int).Cmp(d2.Int) > 0 }      // greater than
   220  func (d Dec) GTE(d2 Dec) bool   { return (d.Int).Cmp(d2.Int) >= 0 }     // greater than or equal
   221  func (d Dec) LT(d2 Dec) bool    { return (d.Int).Cmp(d2.Int) < 0 }      // less than
   222  func (d Dec) LTE(d2 Dec) bool   { return (d.Int).Cmp(d2.Int) <= 0 }     // less than or equal
   223  func (d Dec) Neg() Dec          { return Dec{new(big.Int).Neg(d.Int)} } // reverse the decimal sign
   224  func (d Dec) Abs() Dec          { return Dec{new(big.Int).Abs(d.Int)} } // absolute value
   225  
   226  // BigInt returns a copy of the underlying big.Int.
   227  func (d Dec) BigInt() *big.Int {
   228  	if d.IsNil() {
   229  		return nil
   230  	}
   231  
   232  	copy := new(big.Int)
   233  	return copy.Set(d.Int)
   234  }
   235  
   236  // addition
   237  func (d Dec) Add(d2 Dec) Dec {
   238  	res := new(big.Int).Add(d.Int, d2.Int)
   239  
   240  	if res.BitLen() > 255+DecimalPrecisionBits {
   241  		panic("Int overflow")
   242  	}
   243  	return Dec{res}
   244  }
   245  
   246  // subtraction
   247  func (d Dec) Sub(d2 Dec) Dec {
   248  	res := new(big.Int).Sub(d.Int, d2.Int)
   249  
   250  	if res.BitLen() > 255+DecimalPrecisionBits {
   251  		panic("Int overflow")
   252  	}
   253  	return Dec{res}
   254  }
   255  
   256  // multiplication
   257  func (d Dec) Mul(d2 Dec) Dec {
   258  	mul := new(big.Int).Mul(d.Int, d2.Int)
   259  	chopped := chopPrecisionAndRound(mul)
   260  
   261  	if chopped.BitLen() > 255+DecimalPrecisionBits {
   262  		panic("Int overflow")
   263  	}
   264  	return Dec{chopped}
   265  }
   266  
   267  // multiplication truncate
   268  func (d Dec) MulTruncate(d2 Dec) Dec {
   269  	mul := new(big.Int).Mul(d.Int, d2.Int)
   270  	chopped := chopPrecisionAndTruncate(mul)
   271  
   272  	if chopped.BitLen() > 255+DecimalPrecisionBits {
   273  		panic("Int overflow")
   274  	}
   275  	return Dec{chopped}
   276  }
   277  
   278  // multiplication
   279  func (d Dec) MulInt(i Int) Dec {
   280  	mul := new(big.Int).Mul(d.Int, i.i)
   281  
   282  	if mul.BitLen() > 255+DecimalPrecisionBits {
   283  		panic("Int overflow")
   284  	}
   285  	return Dec{mul}
   286  }
   287  
   288  // MulInt64 - multiplication with int64
   289  func (d Dec) MulInt64(i int64) Dec {
   290  	mul := big.NewInt(i)
   291  	mul = mul.Mul(d.Int, mul)
   292  
   293  	if mul.BitLen() > 255+DecimalPrecisionBits {
   294  		panic("Int overflow")
   295  	}
   296  	return Dec{mul}
   297  }
   298  
   299  // MulInt64To - multiplication with int64 and store result in d2
   300  func (d Dec) MulInt64To(i int64, d2 *Dec) {
   301  	if d2.Int == nil {
   302  		d2.Int = big.NewInt(i)
   303  	} else {
   304  		d2.Int.SetInt64(i)
   305  	}
   306  
   307  	d2.Int.Mul(d.Int, d2.Int)
   308  
   309  	if d2.Int.BitLen() > 255+DecimalPrecisionBits {
   310  		panic("Int overflow")
   311  	}
   312  	return
   313  }
   314  
   315  // quotient
   316  func (d Dec) Quo(d2 Dec) Dec {
   317  	// multiply precision twice
   318  	mul := new(big.Int).Mul(d.Int, precisionReuse)
   319  	mul.Mul(mul, precisionReuse)
   320  
   321  	quo := new(big.Int).Quo(mul, d2.Int)
   322  	chopped := chopPrecisionAndRound(quo)
   323  
   324  	if chopped.BitLen() > 255+DecimalPrecisionBits {
   325  		panic("Int overflow")
   326  	}
   327  	return Dec{chopped}
   328  }
   329  
   330  // quotient truncate
   331  func (d Dec) QuoTruncate(d2 Dec) Dec {
   332  
   333  	// multiply precision twice
   334  	mul := new(big.Int).Mul(d.Int, precisionReuse)
   335  	mul.Mul(mul, precisionReuse)
   336  
   337  	quo := new(big.Int).Quo(mul, d2.Int)
   338  	chopped := chopPrecisionAndTruncate(quo)
   339  
   340  	if chopped.BitLen() > 255+DecimalPrecisionBits {
   341  		panic("Int overflow")
   342  	}
   343  	return Dec{chopped}
   344  }
   345  
   346  // quotient, round up
   347  func (d Dec) QuoRoundUp(d2 Dec) Dec {
   348  	// multiply precision twice
   349  	mul := new(big.Int).Mul(d.Int, precisionReuse)
   350  	mul.Mul(mul, precisionReuse)
   351  
   352  	quo := new(big.Int).Quo(mul, d2.Int)
   353  	chopped := chopPrecisionAndRoundUp(quo)
   354  
   355  	if chopped.BitLen() > 255+DecimalPrecisionBits {
   356  		panic("Int overflow")
   357  	}
   358  	return Dec{chopped}
   359  }
   360  
   361  // quotient
   362  func (d Dec) QuoInt(i Int) Dec {
   363  	mul := new(big.Int).Quo(d.Int, i.i)
   364  	return Dec{mul}
   365  }
   366  
   367  // QuoInt64 - quotient with int64
   368  func (d Dec) QuoInt64(i int64) Dec {
   369  	mul := new(big.Int).Quo(d.Int, big.NewInt(i))
   370  	return Dec{mul}
   371  }
   372  
   373  // ApproxRoot returns an approximate estimation of a Dec's positive real nth root
   374  // using Newton's method (where n is positive). The algorithm starts with some guess and
   375  // computes the sequence of improved guesses until an answer converges to an
   376  // approximate answer.  It returns `|d|.ApproxRoot() * -1` if input is negative.
   377  // A maximum number of 100 iterations is used a backup boundary condition for
   378  // cases where the answer never converges enough to satisfy the main condition.
   379  func (d Dec) ApproxRoot(root uint64) (guess Dec, err error) {
   380  	defer func() {
   381  		if r := recover(); r != nil {
   382  			var ok bool
   383  			err, ok = r.(error)
   384  			if !ok {
   385  				err = errors.New("out of bounds")
   386  			}
   387  		}
   388  	}()
   389  
   390  	if d.IsNegative() {
   391  		absRoot, err := d.MulInt64(-1).ApproxRoot(root)
   392  		return absRoot.MulInt64(-1), err
   393  	}
   394  
   395  	if root == 1 || d.IsZero() || d.Equal(OneDec()) {
   396  		return d, nil
   397  	}
   398  
   399  	if root == 0 {
   400  		return OneDec(), nil
   401  	}
   402  
   403  	rootInt := NewIntFromUint64(root)
   404  	guess, delta := OneDec(), OneDec()
   405  
   406  	for iter := 0; delta.Abs().GT(SmallestDec()) && iter < maxApproxRootIterations; iter++ {
   407  		prev := guess.Power(root - 1)
   408  		if prev.IsZero() {
   409  			prev = SmallestDec()
   410  		}
   411  		delta = d.Quo(prev)
   412  		delta = delta.Sub(guess)
   413  		delta = delta.QuoInt(rootInt)
   414  
   415  		guess = guess.Add(delta)
   416  	}
   417  
   418  	return guess, nil
   419  }
   420  
   421  // Power returns a the result of raising to a positive integer power
   422  func (d Dec) Power(power uint64) Dec {
   423  	if power == 0 {
   424  		return OneDec()
   425  	}
   426  	tmp := OneDec()
   427  	for i := power; i > 1; {
   428  		if i%2 == 0 {
   429  			i /= 2
   430  		} else {
   431  			tmp = tmp.Mul(d)
   432  			i = (i - 1) / 2
   433  		}
   434  		d = d.Mul(d)
   435  	}
   436  	return d.Mul(tmp)
   437  }
   438  
   439  // ApproxSqrt is a wrapper around ApproxRoot for the common special case
   440  // of finding the square root of a number. It returns -(sqrt(abs(d)) if input is negative.
   441  func (d Dec) ApproxSqrt() (Dec, error) {
   442  	return d.ApproxRoot(2)
   443  }
   444  
   445  // is integer, e.g. decimals are zero
   446  func (d Dec) IsInteger() bool {
   447  	return new(big.Int).Rem(d.Int, precisionReuse).Sign() == 0
   448  }
   449  
   450  // format decimal state
   451  func (d Dec) Format(s fmt.State, verb rune) {
   452  	_, err := s.Write(amino.StrToBytes(d.String()))
   453  	if err != nil {
   454  		panic(err)
   455  	}
   456  }
   457  
   458  func (d Dec) String() string {
   459  	if d.Int == nil {
   460  		return d.Int.String()
   461  	}
   462  
   463  	isNeg := d.IsNegative()
   464  	if d.IsNegative() {
   465  		d = d.Neg()
   466  	}
   467  
   468  	bzInt, err := d.Int.MarshalText()
   469  	if err != nil {
   470  		return ""
   471  	}
   472  	inputSize := len(bzInt)
   473  
   474  	var bzStr []byte
   475  
   476  	// TODO: Remove trailing zeros
   477  	// case 1, purely decimal
   478  	if inputSize <= Precision {
   479  		bzStr = make([]byte, Precision+2)
   480  
   481  		// 0. prefix
   482  		bzStr[0] = byte('0')
   483  		bzStr[1] = byte('.')
   484  
   485  		// set relevant digits to 0
   486  		for i := 0; i < Precision-inputSize; i++ {
   487  			bzStr[i+2] = byte('0')
   488  		}
   489  
   490  		// set final digits
   491  		copy(bzStr[2+(Precision-inputSize):], bzInt)
   492  
   493  	} else {
   494  
   495  		// inputSize + 1 to account for the decimal point that is being added
   496  		bzStr = make([]byte, inputSize+1)
   497  		decPointPlace := inputSize - Precision
   498  
   499  		copy(bzStr, bzInt[:decPointPlace])                   // pre-decimal digits
   500  		bzStr[decPointPlace] = byte('.')                     // decimal point
   501  		copy(bzStr[decPointPlace+1:], bzInt[decPointPlace:]) // post-decimal digits
   502  	}
   503  
   504  	if isNeg {
   505  		return "-" + string(bzStr)
   506  	}
   507  
   508  	return amino.BytesToStr(bzStr)
   509  }
   510  
   511  //     ____
   512  //  __|    |__   "chop 'em
   513  //       ` \     round!"
   514  // ___||  ~  _     -bankers
   515  // |         |      __
   516  // |       | |   __|__|__
   517  // |_____:  /   | $$$    |
   518  //              |________|
   519  
   520  // Remove a Precision amount of rightmost digits and perform bankers rounding
   521  // on the remainder (gaussian rounding) on the digits which have been removed.
   522  //
   523  // Mutates the input. Use the non-mutative version if that is undesired
   524  func chopPrecisionAndRound(d *big.Int) *big.Int {
   525  
   526  	// remove the negative and add it back when returning
   527  	if d.Sign() == -1 {
   528  		// make d positive, compute chopped value, and then un-mutate d
   529  		d = d.Neg(d)
   530  		d = chopPrecisionAndRound(d)
   531  		d = d.Neg(d)
   532  		return d
   533  	}
   534  
   535  	// get the truncated quotient and remainder
   536  	quo, rem := d, big.NewInt(0)
   537  	quo, rem = quo.QuoRem(d, precisionReuse, rem)
   538  
   539  	if rem.Sign() == 0 { // remainder is zero
   540  		return quo
   541  	}
   542  
   543  	switch rem.Cmp(fivePrecision) {
   544  	case -1:
   545  		return quo
   546  	case 1:
   547  		return quo.Add(quo, oneInt)
   548  	default: // bankers rounding must take place
   549  		// always round to an even number
   550  		if quo.Bit(0) == 0 {
   551  			return quo
   552  		}
   553  		return quo.Add(quo, oneInt)
   554  	}
   555  }
   556  
   557  func chopPrecisionAndRoundUp(d *big.Int) *big.Int {
   558  
   559  	// remove the negative and add it back when returning
   560  	if d.Sign() == -1 {
   561  		// make d positive, compute chopped value, and then un-mutate d
   562  		d = d.Neg(d)
   563  		// truncate since d is negative...
   564  		d = chopPrecisionAndTruncate(d)
   565  		d = d.Neg(d)
   566  		return d
   567  	}
   568  
   569  	// get the truncated quotient and remainder
   570  	quo, rem := d, big.NewInt(0)
   571  	quo, rem = quo.QuoRem(d, precisionReuse, rem)
   572  
   573  	if rem.Sign() == 0 { // remainder is zero
   574  		return quo
   575  	}
   576  
   577  	return quo.Add(quo, oneInt)
   578  }
   579  
   580  func chopPrecisionAndRoundNonMutative(d *big.Int) *big.Int {
   581  	tmp := new(big.Int).Set(d)
   582  	return chopPrecisionAndRound(tmp)
   583  }
   584  
   585  // RoundInt64 rounds the decimal using bankers rounding
   586  func (d Dec) RoundInt64() int64 {
   587  	chopped := chopPrecisionAndRoundNonMutative(d.Int)
   588  	if !chopped.IsInt64() {
   589  		panic("Int64() out of bound")
   590  	}
   591  	return chopped.Int64()
   592  }
   593  
   594  // RoundInt round the decimal using bankers rounding
   595  func (d Dec) RoundInt() Int {
   596  	return NewIntFromBigInt(chopPrecisionAndRoundNonMutative(d.Int))
   597  }
   598  
   599  //___________________________________________________________________________________
   600  
   601  // similar to chopPrecisionAndRound, but always rounds down
   602  func chopPrecisionAndTruncate(d *big.Int) *big.Int {
   603  	return d.Quo(d, precisionReuse)
   604  }
   605  
   606  func chopPrecisionAndTruncateNonMutative(d *big.Int) *big.Int {
   607  	tmp := new(big.Int).Set(d)
   608  	return chopPrecisionAndTruncate(tmp)
   609  }
   610  
   611  // TruncateInt64 truncates the decimals from the number and returns an int64
   612  func (d Dec) TruncateInt64() int64 {
   613  	chopped := chopPrecisionAndTruncateNonMutative(d.Int)
   614  	if !chopped.IsInt64() {
   615  		panic("Int64() out of bound")
   616  	}
   617  	return chopped.Int64()
   618  }
   619  
   620  // TruncateInt truncates the decimals from the number and returns an Int
   621  func (d Dec) TruncateInt() Int {
   622  	return NewIntFromBigInt(chopPrecisionAndTruncateNonMutative(d.Int))
   623  }
   624  
   625  // TruncateWithPrec truncates an integer based on precision
   626  func (d Dec) TruncateWithPrec(prec int64) Int {
   627  	tmp := new(big.Int).Set(d.Int)
   628  	return NewIntFromBigInt(tmp.Quo(tmp, NewDecWithPrec(1, prec).Int))
   629  }
   630  
   631  // TruncateDec truncates the decimals from the number and returns a Dec
   632  func (d Dec) TruncateDec() Dec {
   633  	return NewDecFromBigInt(chopPrecisionAndTruncateNonMutative(d.Int))
   634  }
   635  
   636  // Ceil returns the smallest interger value (as a decimal) that is greater than
   637  // or equal to the given decimal.
   638  func (d Dec) Ceil() Dec {
   639  	tmp := new(big.Int).Set(d.Int)
   640  
   641  	quo, rem := tmp, big.NewInt(0)
   642  	quo, rem = quo.QuoRem(tmp, precisionReuse, rem)
   643  
   644  	// no need to round with a zero remainder regardless of sign
   645  	if rem.Cmp(zeroInt) == 0 {
   646  		return NewDecFromBigInt(quo)
   647  	}
   648  
   649  	if rem.Sign() == -1 {
   650  		return NewDecFromBigInt(quo)
   651  	}
   652  
   653  	return NewDecFromBigInt(quo.Add(quo, oneInt))
   654  }
   655  
   656  //___________________________________________________________________________________
   657  
   658  // MaxSortableDec is the largest Dec that can be passed into SortableDecBytes()
   659  // Its negative form is the least Dec that can be passed in.
   660  var MaxSortableDec = OneDec().Quo(SmallestDec())
   661  
   662  // ValidSortableDec ensures that a Dec is within the sortable bounds,
   663  // a Dec can't have a precision of less than 10^-18.
   664  // Max sortable decimal was set to the reciprocal of SmallestDec.
   665  func ValidSortableDec(dec Dec) bool {
   666  	return dec.Abs().LTE(MaxSortableDec)
   667  }
   668  
   669  // SortableDecBytes returns a byte slice representation of a Dec that can be sorted.
   670  // Left and right pads with 0s so there are 18 digits to left and right of the decimal point.
   671  // For this reason, there is a maximum and minimum value for this, enforced by ValidSortableDec.
   672  func SortableDecBytes(dec Dec) []byte {
   673  	if !ValidSortableDec(dec) {
   674  		panic("dec must be within bounds")
   675  	}
   676  	// Instead of adding an extra byte to all sortable decs in order to handle max sortable, we just
   677  	// makes its bytes be "max" which comes after all numbers in ASCIIbetical order
   678  	if dec.Equal(MaxSortableDec) {
   679  		return []byte("max")
   680  	}
   681  	// For the same reason, we make the bytes of minimum sortable dec be --, which comes before all numbers.
   682  	if dec.Equal(MaxSortableDec.Neg()) {
   683  		return []byte("--")
   684  	}
   685  	// We move the negative sign to the front of all the left padded 0s, to make negative numbers come before positive numbers
   686  	if dec.IsNegative() {
   687  		return append([]byte("-"), []byte(fmt.Sprintf(fmt.Sprintf("%%0%ds", Precision*2+1), dec.Abs().String()))...)
   688  	}
   689  	return []byte(fmt.Sprintf(fmt.Sprintf("%%0%ds", Precision*2+1), dec.String()))
   690  }
   691  
   692  //___________________________________________________________________________________
   693  
   694  // reuse nil values
   695  var (
   696  	nilAmino string
   697  	nilJSON  []byte
   698  )
   699  
   700  func init() {
   701  	empty := new(big.Int)
   702  	bz, err := empty.MarshalText()
   703  	if err != nil {
   704  		panic("bad nil amino init")
   705  	}
   706  	nilAmino = string(bz)
   707  
   708  	nilJSON, err = json.Marshal(string(bz))
   709  	if err != nil {
   710  		panic("bad nil json init")
   711  	}
   712  }
   713  
   714  // wraps d.MarshalText()
   715  func (d Dec) MarshalAmino() (string, error) {
   716  	if d.Int == nil {
   717  		return nilAmino, nil
   718  	}
   719  	bz, err := d.Int.MarshalText()
   720  	return string(bz), err
   721  }
   722  
   723  // requires a valid JSON string - strings quotes and calls UnmarshalText
   724  func (d *Dec) UnmarshalAmino(text string) (err error) {
   725  	tempInt := new(big.Int)
   726  	err = tempInt.UnmarshalText([]byte(text))
   727  	if err != nil {
   728  		return err
   729  	}
   730  	d.Int = tempInt
   731  	return nil
   732  }
   733  
   734  func (d *Dec) UnmarshalFromAmino(_ *amino.Codec, data []byte) error {
   735  	tempInt := new(big.Int)
   736  	err := tempInt.UnmarshalText(data)
   737  	if err != nil {
   738  		return err
   739  	}
   740  	d.Int = tempInt
   741  	return nil
   742  }
   743  
   744  func (d Dec) MarshalToAmino(_ *amino.Codec) ([]byte, error) {
   745  	if d.Int == nil {
   746  		return []byte(nilAmino), nil
   747  	}
   748  	bz, err := d.Int.MarshalText()
   749  	return bz, err
   750  }
   751  
   752  func (d Dec) AminoSize(_ *amino.Codec) int {
   753  	if d.Int == nil {
   754  		return len(nilAmino)
   755  	}
   756  	return amino.CalcBigIntTextSize(d.Int)
   757  }
   758  
   759  // MarshalJSON marshals the decimal
   760  func (d Dec) MarshalJSON() ([]byte, error) {
   761  	if d.Int == nil {
   762  		return nilJSON, nil
   763  	}
   764  
   765  	return json.Marshal(d.String())
   766  }
   767  
   768  // UnmarshalJSON defines custom decoding scheme
   769  func (d *Dec) UnmarshalJSON(bz []byte) error {
   770  	if d.Int == nil {
   771  		d.Int = new(big.Int)
   772  	}
   773  
   774  	var text string
   775  	err := json.Unmarshal(bz, &text)
   776  	if err != nil {
   777  		return err
   778  	}
   779  	// TODO: Reuse dec allocation
   780  	newDec, err := NewDecFromStr(text)
   781  	if err != nil {
   782  		return err
   783  	}
   784  	d.Int = newDec.Int
   785  	return nil
   786  }
   787  
   788  // MarshalYAML returns Ythe AML representation.
   789  func (d Dec) MarshalYAML() (interface{}, error) { return d.String(), nil }
   790  
   791  //___________________________________________________________________________________
   792  // helpers
   793  
   794  // test if two decimal arrays are equal
   795  func DecsEqual(d1s, d2s []Dec) bool {
   796  	if len(d1s) != len(d2s) {
   797  		return false
   798  	}
   799  
   800  	for i, d1 := range d1s {
   801  		if !d1.Equal(d2s[i]) {
   802  			return false
   803  		}
   804  	}
   805  	return true
   806  }
   807  
   808  // minimum decimal between two
   809  func MinDec(d1, d2 Dec) Dec {
   810  	if d1.LT(d2) {
   811  		return d1
   812  	}
   813  	return d2
   814  }
   815  
   816  // maximum decimal between two
   817  func MaxDec(d1, d2 Dec) Dec {
   818  	if d1.LT(d2) {
   819  		return d2
   820  	}
   821  	return d1
   822  }
   823  
   824  // intended to be used with require/assert:  require.True(DecEq(...))
   825  func DecEq(t *testing.T, exp, got Dec) (*testing.T, bool, string, string, string) {
   826  	return t, exp.Equal(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String()
   827  }
   828  
   829  // Size implements the gogo proto custom type interface.
   830  func (d *Dec) Size() int {
   831  	bz, _ := d.Marshal()
   832  	return len(bz)
   833  }
   834  
   835  func (d Dec) Marshal() ([]byte, error) {
   836  	if d.Int == nil {
   837  		d.Int = new(big.Int)
   838  	}
   839  	return d.Int.MarshalText()
   840  }
   841  
   842  // MarshalTo implements the gogo proto custom type interface.
   843  func (d *Dec) MarshalTo(data []byte) (n int, err error) {
   844  	if d.Int == nil {
   845  		d.Int = new(big.Int)
   846  	}
   847  
   848  	if d.Int.Cmp(zeroInt) == 0 {
   849  		copy(data, []byte{0x30})
   850  		return 1, nil
   851  	}
   852  
   853  	bz, err := d.Marshal()
   854  	if err != nil {
   855  		return 0, err
   856  	}
   857  
   858  	copy(data, bz)
   859  	return len(bz), nil
   860  }
   861  
   862  // Unmarshal implements the gogo proto custom type interface.
   863  func (d *Dec) Unmarshal(data []byte) error {
   864  	if len(data) == 0 {
   865  		d = nil
   866  		return nil
   867  	}
   868  
   869  	if d.Int == nil {
   870  		d.Int = new(big.Int)
   871  	}
   872  
   873  	if err := d.Int.UnmarshalText(data); err != nil {
   874  		return err
   875  	}
   876  
   877  	if d.Int.BitLen() > maxBitLen {
   878  		return fmt.Errorf("decimal out of range; got: %d, max: %d", d.Int.BitLen(), maxBitLen)
   879  	}
   880  
   881  	return nil
   882  }