github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/util/encoding/decimal.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  //
    11  // An ordered key encoding scheme for arbitrary-precision fixed-point
    12  // numeric values based on sqlite4's key encoding:
    13  // http://sqlite.org/src4/doc/trunk/www/key_encoding.wiki
    14  
    15  package encoding
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"math"
    21  	"math/big"
    22  	"unsafe"
    23  
    24  	"github.com/cockroachdb/apd/v3"
    25  	"github.com/cockroachdb/errors"
    26  )
    27  
    28  // EncodeDecimalAscending returns the resulting byte slice with the encoded decimal
    29  // appended to the given buffer.
    30  //
    31  // Values are classified as large, medium, or small according to the value of
    32  // E. If E is 11 or more, the value is large. For E between 0 and 10, the value
    33  // is medium. For E less than zero, the value is small.
    34  //
    35  // Large positive values are encoded as a single byte 0x34 followed by E as a
    36  // varint and then M. Medium positive values are a single byte of 0x29+E
    37  // followed by M. Small positive values are encoded as a single byte 0x28
    38  // followed by a descending varint encoding for -E followed by M.
    39  //
    40  // Small negative values are encoded as a single byte 0x26 followed by -E as a
    41  // varint and then the ones-complement of M. Medium negative values are encoded
    42  // as a byte 0x25-E followed by the ones-complement of M. Large negative values
    43  // consist of the single byte 0x1a followed by a descending  varint encoding of
    44  // E followed by the ones-complement of M.
    45  func EncodeDecimalAscending(appendTo []byte, d *apd.Decimal) []byte {
    46  	return encodeDecimal(appendTo, d, false)
    47  }
    48  
    49  // EncodeDecimalDescending is the descending version of EncodeDecimalAscending.
    50  func EncodeDecimalDescending(appendTo []byte, d *apd.Decimal) []byte {
    51  	return encodeDecimal(appendTo, d, true)
    52  }
    53  
    54  func encodeDecimal(appendTo []byte, d *apd.Decimal, invert bool) []byte {
    55  	if d.IsZero() {
    56  		// Negative and positive zero are encoded identically. Only nonsorting
    57  		// decimal encoding can retain the sign.
    58  		return append(appendTo, decimalZero)
    59  	}
    60  	neg := d.Negative != invert
    61  	switch d.Form {
    62  	case apd.Finite:
    63  		// ignore
    64  	case apd.Infinite:
    65  		if neg {
    66  			return append(appendTo, decimalNegativeInfinity)
    67  		}
    68  		return append(appendTo, decimalInfinity)
    69  	case apd.NaN:
    70  		if invert {
    71  			return append(appendTo, decimalNaNDesc)
    72  		}
    73  		return append(appendTo, decimalNaN)
    74  	default:
    75  		panic(errors.Errorf("unknown form: %s", d.Form))
    76  	}
    77  	e, m := decimalEandM(d, appendTo[len(appendTo):])
    78  	return encodeEandM(appendTo, neg, e, m)
    79  }
    80  
    81  // decimalEandM computes and returns the exponent E and mantissa M for d.
    82  //
    83  // The mantissa is a base-100 representation of the value. The exponent E
    84  // determines where to put the decimal point.
    85  //
    86  // Each centimal digit of the mantissa is stored in a byte. If the value of the
    87  // centimal digit is X (hence X>=0 and X<=99) then the byte value will be 2*X+1
    88  // for every byte of the mantissa, except for the last byte which will be
    89  // 2*X+0. The mantissa must be the minimum number of bytes necessary to
    90  // represent the value; trailing X==0 digits are omitted.  This means that the
    91  // mantissa will never contain a byte with the value 0x00.
    92  //
    93  // If we assume all digits of the mantissa occur to the right of the decimal
    94  // point, then the exponent E is the power of one hundred by which one must
    95  // multiply the mantissa to recover the original value.
    96  func decimalEandM(d *apd.Decimal, tmp []byte) (int, []byte) {
    97  	addedZero := false
    98  	if cap(tmp) > 0 {
    99  		tmp = tmp[:1]
   100  		tmp[0] = '0'
   101  		addedZero = true
   102  	}
   103  	tmp = d.Coeff.Append(tmp, 10)
   104  	if !addedZero {
   105  		tmp = append(tmp, '0')
   106  		copy(tmp[1:], tmp[:len(tmp)-1])
   107  		tmp[0] = '0'
   108  	}
   109  
   110  	// The exponent will be the combination of the decimal's exponent, and the
   111  	// number of digits in the big.Int.
   112  	e10 := int(d.Exponent) + len(tmp[1:])
   113  
   114  	// Strip off trailing zeros in big.Int's string representation.
   115  	for tmp[len(tmp)-1] == '0' {
   116  		tmp = tmp[:len(tmp)-1]
   117  	}
   118  
   119  	// Convert the power-10 exponent to a power of 100 exponent.
   120  	var e100 int
   121  	if e10 >= 0 {
   122  		e100 = (e10 + 1) / 2
   123  	} else {
   124  		e100 = e10 / 2
   125  	}
   126  	// Strip the leading 0 if the conversion to e100 did not add a multiple of
   127  	// 10.
   128  	if e100*2 == e10 {
   129  		tmp = tmp[1:]
   130  	}
   131  
   132  	// Ensure that the number of digits is even.
   133  	if len(tmp)%2 != 0 {
   134  		tmp = append(tmp, '0')
   135  	}
   136  
   137  	// Convert the base-10 'b' slice to a base-100 'm' slice. We do this
   138  	// conversion in place to avoid an allocation.
   139  	m := tmp[:len(tmp)/2]
   140  	for i := 0; i < len(tmp); i += 2 {
   141  		accum := 10*int(tmp[i]-'0') + int(tmp[i+1]-'0')
   142  		// The bytes are encoded as 2n+1.
   143  		m[i/2] = byte(2*accum + 1)
   144  	}
   145  	// The last byte is encoded as 2n+0.
   146  	m[len(m)-1]--
   147  	return e100, m
   148  }
   149  
   150  // encodeEandM encodes the exponent and mantissa, appending the encoding to a byte buffer.
   151  //
   152  // The mantissa m can be stored in the spare capacity of appendTo.
   153  func encodeEandM(appendTo []byte, negative bool, e int, m []byte) []byte {
   154  	var buf []byte
   155  	if n := len(m) + MaxVarintLen + 2; n <= cap(appendTo)-len(appendTo) {
   156  		buf = appendTo[len(appendTo) : len(appendTo)+n]
   157  	} else {
   158  		buf = make([]byte, n)
   159  	}
   160  	switch {
   161  	case e < 0:
   162  		return append(appendTo, encodeSmallNumber(negative, e, m, buf)...)
   163  	case e >= 0 && e <= 10:
   164  		return append(appendTo, encodeMediumNumber(negative, e, m, buf)...)
   165  	case e >= 11:
   166  		return append(appendTo, encodeLargeNumber(negative, e, m, buf)...)
   167  	}
   168  	panic("unreachable")
   169  }
   170  
   171  // encodeVarExpNumber encodes a Uvarint exponent and mantissa into a buffer;
   172  // only used for small (less than 0) and large (greater than 10) exponents.
   173  //
   174  // If required, the mantissa should already be in ones complement.
   175  //
   176  // The encoding must fit in encInto. The mantissa m can overlap with encInto.
   177  //
   178  // Returns the length-adjusted buffer.
   179  func encodeVarExpNumber(tag byte, expAscending bool, exp uint64, m []byte, encInto []byte) []byte {
   180  	// Because m can overlap with encInto, we must first copy m to the right place
   181  	// before modifying encInto.
   182  	var n int
   183  	if expAscending {
   184  		n = EncLenUvarintAscending(exp)
   185  	} else {
   186  		n = EncLenUvarintDescending(exp)
   187  	}
   188  	l := 1 + n + len(m)
   189  	if len(encInto) < l+1 {
   190  		panic("buffer too short")
   191  	}
   192  	copy(encInto[1+n:], m)
   193  	encInto[0] = tag
   194  	if expAscending {
   195  		EncodeUvarintAscending(encInto[1:1], exp)
   196  	} else {
   197  		EncodeUvarintDescending(encInto[1:1], exp)
   198  	}
   199  	encInto[l] = decimalTerminator
   200  	return encInto[:l+1]
   201  }
   202  
   203  // encodeSmallNumber encodes the exponent and mantissa into a buffer; only used
   204  // when the exponent is negative. See encodeVarExpNumber.
   205  func encodeSmallNumber(negative bool, e int, m []byte, encInto []byte) []byte {
   206  	if negative {
   207  		onesComplement(m)
   208  		return encodeVarExpNumber(decimalNegSmall, true, uint64(-e), m, encInto)
   209  	}
   210  	return encodeVarExpNumber(decimalPosSmall, false, uint64(-e), m, encInto)
   211  }
   212  
   213  // encodeLargeNumber encodes the exponent and mantissa into a buffer; only used
   214  // when the exponent is larger than 10. See encodeVarExpNumber.
   215  func encodeLargeNumber(negative bool, e int, m []byte, encInto []byte) []byte {
   216  	if negative {
   217  		onesComplement(m)
   218  		return encodeVarExpNumber(decimalNegLarge, false, uint64(e), m, encInto)
   219  	}
   220  	return encodeVarExpNumber(decimalPosLarge, true, uint64(e), m, encInto)
   221  }
   222  
   223  // encodeMediumNumber encodes the exponent and mantissa into a buffer, only used
   224  // when the exponent is in [0, 10].
   225  //
   226  // The encoding must fit in encInto. The mantissa m can overlap with encInto.
   227  //
   228  // Returns the length-adjusted buffer.
   229  func encodeMediumNumber(negative bool, e int, m []byte, encInto []byte) []byte {
   230  	l := 1 + len(m)
   231  	if len(encInto) < l+1 {
   232  		panic("buffer too short")
   233  	}
   234  	// Because m can overlap with encInto, we must first copy m to the right place
   235  	// before modifying encInto.
   236  	copy(encInto[1:], m)
   237  	if negative {
   238  		encInto[0] = decimalNegMedium - byte(e)
   239  		onesComplement(encInto[1:l])
   240  	} else {
   241  		encInto[0] = decimalPosMedium + byte(e)
   242  	}
   243  	encInto[l] = decimalTerminator
   244  	return encInto[:l+1]
   245  }
   246  
   247  // DecodeDecimalAscending returns the remaining byte slice after decoding and the decoded
   248  // decimal from buf.
   249  func DecodeDecimalAscending(buf []byte, tmp []byte) ([]byte, apd.Decimal, error) {
   250  	return decodeDecimal(buf, tmp, false)
   251  }
   252  
   253  // DecodeDecimalDescending decodes decimals encoded with EncodeDecimalDescending.
   254  func DecodeDecimalDescending(buf []byte, tmp []byte) ([]byte, apd.Decimal, error) {
   255  	return decodeDecimal(buf, tmp, true)
   256  }
   257  
   258  func decodeDecimal(buf []byte, tmp []byte, invert bool) ([]byte, apd.Decimal, error) {
   259  	// Handle the simplistic cases first.
   260  	switch buf[0] {
   261  	case decimalNaN, decimalNaNDesc:
   262  		return buf[1:], apd.Decimal{Form: apd.NaN}, nil
   263  	case decimalInfinity:
   264  		return buf[1:], apd.Decimal{Form: apd.Infinite, Negative: invert}, nil
   265  	case decimalNegativeInfinity:
   266  		return buf[1:], apd.Decimal{Form: apd.Infinite, Negative: !invert}, nil
   267  	case decimalZero:
   268  		return buf[1:], apd.Decimal{}, nil
   269  	}
   270  	tmp = tmp[len(tmp):cap(tmp)]
   271  	switch {
   272  	case buf[0] == decimalNegLarge:
   273  		// Negative large.
   274  		e, m, r, tmp2, err := decodeLargeNumber(true, buf, tmp)
   275  		if err != nil {
   276  			return nil, apd.Decimal{}, err
   277  		}
   278  		d, err := makeDecimalFromMandE(!invert, e, m, tmp2)
   279  		return r, d, err
   280  	case buf[0] > decimalNegLarge && buf[0] <= decimalNegMedium:
   281  		// Negative medium.
   282  		e, m, r, tmp2, err := decodeMediumNumber(true, buf, tmp)
   283  		if err != nil {
   284  			return nil, apd.Decimal{}, err
   285  		}
   286  		d, err := makeDecimalFromMandE(!invert, e, m, tmp2)
   287  		return r, d, err
   288  	case buf[0] == decimalNegSmall:
   289  		// Negative small.
   290  		e, m, r, tmp2, err := decodeSmallNumber(true, buf, tmp)
   291  		if err != nil {
   292  			return nil, apd.Decimal{}, err
   293  		}
   294  		d, err := makeDecimalFromMandE(!invert, e, m, tmp2)
   295  		return r, d, err
   296  	case buf[0] == decimalPosLarge:
   297  		// Positive large.
   298  		e, m, r, tmp2, err := decodeLargeNumber(false, buf, tmp)
   299  		if err != nil {
   300  			return nil, apd.Decimal{}, err
   301  		}
   302  		d, err := makeDecimalFromMandE(invert, e, m, tmp2)
   303  		return r, d, err
   304  	case buf[0] >= decimalPosMedium && buf[0] < decimalPosLarge:
   305  		// Positive medium.
   306  		e, m, r, tmp2, err := decodeMediumNumber(false, buf, tmp)
   307  		if err != nil {
   308  			return nil, apd.Decimal{}, err
   309  		}
   310  		d, err := makeDecimalFromMandE(invert, e, m, tmp2)
   311  		return r, d, err
   312  	case buf[0] == decimalPosSmall:
   313  		// Positive small.
   314  		e, m, r, tmp2, err := decodeSmallNumber(false, buf, tmp)
   315  		if err != nil {
   316  			return nil, apd.Decimal{}, err
   317  		}
   318  		d, err := makeDecimalFromMandE(invert, e, m, tmp2)
   319  		return r, d, err
   320  	default:
   321  		return nil, apd.Decimal{}, errors.Errorf("unknown prefix of the encoded byte slice: %q", buf)
   322  	}
   323  }
   324  
   325  // getDecimalLen returns the length of an encoded decimal.
   326  func getDecimalLen(buf []byte) (int, error) {
   327  	m := buf[0]
   328  	p := 1
   329  	if m < decimalNaN || m > decimalNaNDesc {
   330  		panic(fmt.Errorf("invalid tag %d", m))
   331  	}
   332  	switch m {
   333  	case decimalNaN, decimalNegativeInfinity, decimalNaNDesc, decimalInfinity, decimalZero:
   334  		return 1, nil
   335  	case decimalNegLarge, decimalNegSmall, decimalPosLarge, decimalPosSmall:
   336  		// Skip the varint exponent.
   337  		l, err := getVarintLen(buf[p:])
   338  		if err != nil {
   339  			return 0, err
   340  		}
   341  		p += l
   342  	}
   343  
   344  	idx, err := findDecimalTerminator(buf[p:])
   345  	if err != nil {
   346  		return 0, err
   347  	}
   348  	return p + idx + 1, nil
   349  }
   350  
   351  // makeDecimalFromMandE reconstructs the decimal from the mantissa M and
   352  // exponent E.
   353  func makeDecimalFromMandE(negative bool, e int, m []byte, tmp []byte) (apd.Decimal, error) {
   354  	if len(m) == 0 {
   355  		return apd.Decimal{}, errors.New("expected mantissa, got zero bytes")
   356  	}
   357  	// ±dddd.
   358  	b := tmp[:0]
   359  	if n := len(m)*2 + 1; cap(b) < n {
   360  		b = make([]byte, 0, n)
   361  	}
   362  	for _, v := range m {
   363  		t := int(v) / 2
   364  		if t < 0 || t > 99 {
   365  			return apd.Decimal{}, errors.Errorf("base-100 encoded digit %d out of range [0,99]", t)
   366  		}
   367  		b = append(b, byte(t/10)+'0', byte(t%10)+'0')
   368  	}
   369  	if b[len(b)-1] == '0' {
   370  		b = b[:len(b)-1]
   371  	}
   372  
   373  	exp := 2*e - len(b)
   374  	dec := apd.Decimal{
   375  		Exponent: int32(exp),
   376  	}
   377  
   378  	// We unsafely convert the []byte to a string to avoid the usual allocation
   379  	// when converting to a string.
   380  	s := *(*string)(unsafe.Pointer(&b))
   381  	_, ok := dec.Coeff.SetString(s, 10)
   382  	if !ok {
   383  		return apd.Decimal{}, errors.Errorf("could not set big.Int's string value: %q", s)
   384  	}
   385  	dec.Negative = negative
   386  
   387  	return dec, nil
   388  }
   389  
   390  // findDecimalTerminator finds the decimalTerminator in the given slice.
   391  func findDecimalTerminator(buf []byte) (int, error) {
   392  	if idx := bytes.IndexByte(buf, decimalTerminator); idx != -1 {
   393  		return idx, nil
   394  	}
   395  	return -1, errors.Errorf("did not find terminator %#x in buffer %#x", decimalTerminator, buf)
   396  }
   397  
   398  func decodeSmallNumber(
   399  	negative bool, buf []byte, tmp []byte,
   400  ) (e int, m []byte, rest []byte, newTmp []byte, err error) {
   401  	var ex uint64
   402  	var r []byte
   403  	if negative {
   404  		r, ex, err = DecodeUvarintAscending(buf[1:])
   405  	} else {
   406  		r, ex, err = DecodeUvarintDescending(buf[1:])
   407  	}
   408  	if err != nil {
   409  		return 0, nil, nil, nil, err
   410  	}
   411  
   412  	idx, err := findDecimalTerminator(r)
   413  	if err != nil {
   414  		return 0, nil, nil, nil, err
   415  	}
   416  
   417  	m = r[:idx]
   418  	if negative {
   419  		var mCpy []byte
   420  		if k := len(m); k <= len(tmp) {
   421  			mCpy = tmp[:k]
   422  			tmp = tmp[k:]
   423  		} else {
   424  			mCpy = make([]byte, k)
   425  		}
   426  		copy(mCpy, m)
   427  		onesComplement(mCpy)
   428  		m = mCpy
   429  	}
   430  	return int(-ex), m, r[idx+1:], tmp, nil
   431  }
   432  
   433  func decodeMediumNumber(
   434  	negative bool, buf []byte, tmp []byte,
   435  ) (e int, m []byte, rest []byte, newTmp []byte, err error) {
   436  	idx, err := findDecimalTerminator(buf[1:])
   437  	if err != nil {
   438  		return 0, nil, nil, nil, err
   439  	}
   440  
   441  	m = buf[1 : idx+1]
   442  	if negative {
   443  		e = int(decimalNegMedium - buf[0])
   444  		var mCpy []byte
   445  		if k := len(m); k <= len(tmp) {
   446  			mCpy = tmp[:k]
   447  			tmp = tmp[k:]
   448  		} else {
   449  			mCpy = make([]byte, k)
   450  		}
   451  		copy(mCpy, m)
   452  		onesComplement(mCpy)
   453  		m = mCpy
   454  	} else {
   455  		e = int(buf[0] - decimalPosMedium)
   456  	}
   457  	return e, m, buf[idx+2:], tmp, nil
   458  }
   459  
   460  func decodeLargeNumber(
   461  	negative bool, buf []byte, tmp []byte,
   462  ) (e int, m []byte, rest []byte, newTmp []byte, err error) {
   463  	var ex uint64
   464  	var r []byte
   465  	if negative {
   466  		r, ex, err = DecodeUvarintDescending(buf[1:])
   467  	} else {
   468  		r, ex, err = DecodeUvarintAscending(buf[1:])
   469  	}
   470  	if err != nil {
   471  		return 0, nil, nil, nil, err
   472  	}
   473  
   474  	idx, err := findDecimalTerminator(r)
   475  	if err != nil {
   476  		return 0, nil, nil, nil, err
   477  	}
   478  
   479  	m = r[:idx]
   480  	if negative {
   481  		var mCpy []byte
   482  		if k := len(m); k <= len(tmp) {
   483  			mCpy = tmp[:k]
   484  			tmp = tmp[k:]
   485  		} else {
   486  			mCpy = make([]byte, k)
   487  		}
   488  		copy(mCpy, m)
   489  		onesComplement(mCpy)
   490  		m = mCpy
   491  	}
   492  	return int(ex), m, r[idx+1:], tmp, nil
   493  }
   494  
   495  // EncodeNonsortingDecimal returns the resulting byte slice with the
   496  // encoded decimal appended to b. The encoding is limited compared to
   497  // standard encodings in this package in that
   498  //   - It will not sort lexicographically
   499  //   - It does not encode its length or terminate itself, so decoding
   500  //     functions must be provided the exact encoded bytes
   501  //
   502  // The encoding assumes that any number can be written as ±0.xyz... * 10^exp,
   503  // where xyz is a digit string, x != 0, and the last decimal in xyz is also
   504  // not 0.
   505  //
   506  // The encoding uses its first byte to split decimals into 7 distinct
   507  // ordered groups (no NaN or Infinity support yet). The groups can
   508  // be seen in encoding.go's const definition. Following this, the
   509  // absolute value of the exponent of the decimal (as defined above)
   510  // is encoded as an unsigned varint. Second, the absolute value of
   511  // the digit string is added as a big-endian byte slice.
   512  //
   513  // All together, the encoding looks like:
   514  //
   515  //	<marker><uvarint exponent><big-endian encoded big.Int>.
   516  //
   517  // The markers are shared with the sorting decimal encoding as follows:
   518  //
   519  //	decimalNaN              -> decimalNaN
   520  //	decimalNegativeInfinity -> decimalNegativeInfinity
   521  //	decimalNegLarge         -> decimalNegValPosExp
   522  //	decimalNegMedium        -> decimalNegValZeroExp
   523  //	decimalNegSmall         -> decimalNegValNegExp
   524  //	decimalZero             -> decimalZero
   525  //	decimalPosSmall         -> decimalPosValNegExp
   526  //	decimalPosMedium        -> decimalPosValZeroExp
   527  //	decimalPosLarge         -> decimalPosValPosExp
   528  //	decimalInfinity         -> decimalInfinity
   529  //	decimalNaNDesc          -> decimalNaNDesc
   530  func EncodeNonsortingDecimal(b []byte, d *apd.Decimal) []byte {
   531  	neg := d.Negative
   532  	switch d.Form {
   533  	case apd.Finite:
   534  		// ignore
   535  	case apd.Infinite:
   536  		if neg {
   537  			return append(b, decimalNegativeInfinity)
   538  		}
   539  		return append(b, decimalInfinity)
   540  	case apd.NaN:
   541  		return append(b, decimalNaN)
   542  	default:
   543  		panic(errors.Errorf("unknown form: %s", d.Form))
   544  	}
   545  
   546  	// We only encode "0" as decimalZero. All others ("0.0", "-0", etc) are
   547  	// encoded like normal values.
   548  	if d.IsZero() && !neg && d.Exponent == 0 {
   549  		return append(b, decimalZero)
   550  	}
   551  
   552  	// Determine the exponent of the decimal, with the
   553  	// exponent defined as .xyz * 10^exp.
   554  	nDigits := int(d.NumDigits())
   555  	e := nDigits + int(d.Exponent)
   556  
   557  	bNat := d.Coeff.Bits()
   558  
   559  	var buf []byte
   560  	if n := UpperBoundNonsortingDecimalSize(d); n <= cap(b)-len(b) {
   561  		// We append the marker directly to the input buffer b below, so
   562  		// we are off by 1 for each of these, which explains the adjustments.
   563  		buf = b[len(b)+1 : len(b)+1]
   564  	} else {
   565  		buf = make([]byte, 0, n-1)
   566  	}
   567  
   568  	switch {
   569  	case neg && e > 0:
   570  		b = append(b, decimalNegLarge)
   571  		buf = encodeNonsortingDecimalValue(uint64(e), bNat, buf)
   572  		return append(b, buf...)
   573  	case neg && e == 0:
   574  		b = append(b, decimalNegMedium)
   575  		buf = encodeNonsortingDecimalValueWithoutExp(bNat, buf)
   576  		return append(b, buf...)
   577  	case neg && e < 0:
   578  		b = append(b, decimalNegSmall)
   579  		buf = encodeNonsortingDecimalValue(uint64(-e), bNat, buf)
   580  		return append(b, buf...)
   581  	case !neg && e < 0:
   582  		b = append(b, decimalPosSmall)
   583  		buf = encodeNonsortingDecimalValue(uint64(-e), bNat, buf)
   584  		return append(b, buf...)
   585  	case !neg && e == 0:
   586  		b = append(b, decimalPosMedium)
   587  		buf = encodeNonsortingDecimalValueWithoutExp(bNat, buf)
   588  		return append(b, buf...)
   589  	case !neg && e > 0:
   590  		b = append(b, decimalPosLarge)
   591  		buf = encodeNonsortingDecimalValue(uint64(e), bNat, buf)
   592  		return append(b, buf...)
   593  	}
   594  	panic("unreachable")
   595  }
   596  
   597  // encodeNonsortingDecimalValue encodes the absolute value of a decimal's
   598  // exponent and slice of digit bytes into buf, returning the populated buffer
   599  // after encoding. The function first encodes the absolute value of a
   600  // decimal's exponent as an unsigned varint. Following this, it copies the
   601  // decimal's big-endian digits themselves into the buffer.
   602  func encodeNonsortingDecimalValue(exp uint64, digits []big.Word, buf []byte) []byte {
   603  	// Encode the exponent using a Uvarint.
   604  	buf = EncodeUvarintAscending(buf, exp)
   605  
   606  	// Encode the digits into the end of the byte slice.
   607  	return copyWords(buf, digits)
   608  }
   609  
   610  func encodeNonsortingDecimalValueWithoutExp(digits []big.Word, buf []byte) []byte {
   611  	// Encode the digits into the end of the byte slice.
   612  	return copyWords(buf, digits)
   613  }
   614  
   615  // DecodeNonsortingDecimal returns the decoded decimal from buf encoded with
   616  // EncodeNonsortingDecimal. buf is assumed to contain only the encoded decimal,
   617  // as the function does not know from the encoding itself what the length
   618  // of the encoded value is.
   619  func DecodeNonsortingDecimal(buf []byte, tmp []byte) (apd.Decimal, error) {
   620  	var dec apd.Decimal
   621  	err := DecodeIntoNonsortingDecimal(&dec, buf, tmp)
   622  	return dec, err
   623  }
   624  
   625  // DecodeIntoNonsortingDecimal is like DecodeNonsortingDecimal, but it operates
   626  // on the passed-in *apd.Decimal instead of producing a new one.
   627  func DecodeIntoNonsortingDecimal(dec *apd.Decimal, buf []byte, tmp []byte) error {
   628  	*dec = apd.Decimal{}
   629  	switch buf[0] {
   630  	case decimalNaN:
   631  		dec.Form = apd.NaN
   632  		return nil
   633  	case decimalNegativeInfinity:
   634  		dec.Form = apd.Infinite
   635  		dec.Negative = true
   636  		return nil
   637  	case decimalInfinity:
   638  		dec.Form = apd.Infinite
   639  		return nil
   640  	case decimalZero:
   641  		return nil
   642  	}
   643  
   644  	dec.Form = apd.Finite
   645  	switch {
   646  	case buf[0] == decimalNegLarge:
   647  		if err := decodeNonsortingDecimalValue(dec, false, buf[1:], tmp); err != nil {
   648  			return err
   649  		}
   650  		dec.Negative = true
   651  		return nil
   652  	case buf[0] == decimalNegMedium:
   653  		decodeNonsortingDecimalValueWithoutExp(dec, buf[1:], tmp)
   654  		dec.Negative = true
   655  		return nil
   656  	case buf[0] == decimalNegSmall:
   657  		if err := decodeNonsortingDecimalValue(dec, true, buf[1:], tmp); err != nil {
   658  			return err
   659  		}
   660  		dec.Negative = true
   661  		return nil
   662  	case buf[0] == decimalPosSmall:
   663  		if err := decodeNonsortingDecimalValue(dec, true, buf[1:], tmp); err != nil {
   664  			return err
   665  		}
   666  		return nil
   667  	case buf[0] == decimalPosMedium:
   668  		decodeNonsortingDecimalValueWithoutExp(dec, buf[1:], tmp)
   669  		return nil
   670  	case buf[0] == decimalPosLarge:
   671  		if err := decodeNonsortingDecimalValue(dec, false, buf[1:], tmp); err != nil {
   672  			return err
   673  		}
   674  		return nil
   675  	default:
   676  		return errors.Errorf("unknown decimal prefix of the encoded byte slice: %q", buf)
   677  	}
   678  }
   679  
   680  func decodeNonsortingDecimalValue(dec *apd.Decimal, negExp bool, buf, tmp []byte) error {
   681  	// Decode the exponent.
   682  	buf, e, err := DecodeUvarintAscending(buf)
   683  	if err != nil {
   684  		return err
   685  	}
   686  	if negExp {
   687  		e = -e
   688  	}
   689  
   690  	bi := &dec.Coeff
   691  	bi.SetBytes(buf)
   692  
   693  	// Set the decimal's scale.
   694  	nDigits := int(apd.NumDigits(bi))
   695  	exp := int(e) - nDigits
   696  	dec.Exponent = int32(exp)
   697  	return nil
   698  }
   699  
   700  func decodeNonsortingDecimalValueWithoutExp(dec *apd.Decimal, buf, tmp []byte) {
   701  	bi := &dec.Coeff
   702  	bi.SetBytes(buf)
   703  
   704  	// Set the decimal's scale.
   705  	nDigits := apd.NumDigits(bi)
   706  	dec.Exponent = -int32(nDigits)
   707  }
   708  
   709  // UpperBoundNonsortingDecimalSize returns the upper bound number of bytes
   710  // that the decimal will need for the non-sorting encoding.
   711  func UpperBoundNonsortingDecimalSize(d *apd.Decimal) int {
   712  	// Makeup of upper bound size:
   713  	// - 1 byte for the prefix
   714  	// - MaxVarintLen for the exponent
   715  	// - WordLen for the big.Int bytes
   716  	return 1 + MaxVarintLen + WordLen(d.Coeff.Bits())
   717  }
   718  
   719  // upperBoundNonsortingDecimalUnscaledSize is the same as
   720  // UpperBoundNonsortingDecimalSize but for a decimal with the given unscaled
   721  // length. The upper bound here may not be as tight as the one returned by
   722  // UpperBoundNonsortingDecimalSize.
   723  func upperBoundNonsortingDecimalUnscaledSize(unscaledLen int) int {
   724  	// The number of digits needed to represent a base 10 number of length
   725  	// unscaledLen in base 2.
   726  	unscaledLenBase2 := float64(unscaledLen) * math.Log2(10)
   727  	unscaledLenBase2Words := math.Ceil(unscaledLenBase2 / 8 / float64(bigWordSize))
   728  	unscaledLenWordRounded := int(unscaledLenBase2Words) * bigWordSize
   729  	// Makeup of upper bound size:
   730  	// - 1 byte for the prefix
   731  	// - MaxVarintLen for the exponent
   732  	// - unscaledLenWordRounded for the big.Int bytes
   733  	return 1 + MaxVarintLen + unscaledLenWordRounded
   734  }
   735  
   736  // Taken from math/big/arith.go.
   737  const bigWordSize = int(unsafe.Sizeof(big.Word(0)))
   738  
   739  // WordLen returns the size in bytes of the given array of Words.
   740  func WordLen(nat []big.Word) int {
   741  	return len(nat) * bigWordSize
   742  }
   743  
   744  // copyWords was adapted from math/big/nat.go. It writes the value of
   745  // nat into buf using big-endian encoding. len(buf) must be >= len(nat)*bigWordSize.
   746  func copyWords(buf []byte, nat []big.Word) []byte {
   747  	// Omit leading zeros from the resulting byte slice, which is both
   748  	// safe and exactly what big.Int.Bytes() does. See big.nat.setBytes()
   749  	// and big.nat.norm() for how this is normalized on decoding.
   750  	leading := true
   751  	for w := len(nat) - 1; w >= 0; w-- {
   752  		d := nat[w]
   753  		for j := bigWordSize - 1; j >= 0; j-- {
   754  			by := byte(d >> (8 * big.Word(j)))
   755  			if by == 0 && leading {
   756  				continue
   757  			}
   758  			leading = false
   759  			buf = append(buf, by)
   760  		}
   761  	}
   762  	return buf
   763  }