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 }