github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/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" 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) + maxVarintSize + 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 // <marker><uvarint exponent><big-endian encoded big.Int>. 515 // 516 // The markers are shared with the sorting decimal encoding as follows: 517 // decimalNaN -> decimalNaN 518 // decimalNegativeInfinity -> decimalNegativeInfinity 519 // decimalNegLarge -> decimalNegValPosExp 520 // decimalNegMedium -> decimalNegValZeroExp 521 // decimalNegSmall -> decimalNegValNegExp 522 // decimalZero -> decimalZero 523 // decimalPosSmall -> decimalPosValNegExp 524 // decimalPosMedium -> decimalPosValZeroExp 525 // decimalPosLarge -> decimalPosValPosExp 526 // decimalInfinity -> decimalInfinity 527 // decimalNaNDesc -> decimalNaNDesc 528 // 529 func EncodeNonsortingDecimal(b []byte, d *apd.Decimal) []byte { 530 neg := d.Negative 531 switch d.Form { 532 case apd.Finite: 533 // ignore 534 case apd.Infinite: 535 if neg { 536 return append(b, decimalNegativeInfinity) 537 } 538 return append(b, decimalInfinity) 539 case apd.NaN: 540 return append(b, decimalNaN) 541 default: 542 panic(errors.Errorf("unknown form: %s", d.Form)) 543 } 544 545 // We only encode "0" as decimalZero. All others ("0.0", "-0", etc) are 546 // encoded like normal values. 547 if d.IsZero() && !neg && d.Exponent == 0 { 548 return append(b, decimalZero) 549 } 550 551 // Determine the exponent of the decimal, with the 552 // exponent defined as .xyz * 10^exp. 553 nDigits := int(d.NumDigits()) 554 e := nDigits + int(d.Exponent) 555 556 bNat := d.Coeff.Bits() 557 558 var buf []byte 559 if n := UpperBoundNonsortingDecimalSize(d); n <= cap(b)-len(b) { 560 // We append the marker directly to the input buffer b below, so 561 // we are off by 1 for each of these, which explains the adjustments. 562 buf = b[len(b)+1 : len(b)+1] 563 } else { 564 buf = make([]byte, 0, n-1) 565 } 566 567 switch { 568 case neg && e > 0: 569 b = append(b, decimalNegLarge) 570 buf = encodeNonsortingDecimalValue(uint64(e), bNat, buf) 571 return append(b, buf...) 572 case neg && e == 0: 573 b = append(b, decimalNegMedium) 574 buf = encodeNonsortingDecimalValueWithoutExp(bNat, buf) 575 return append(b, buf...) 576 case neg && e < 0: 577 b = append(b, decimalNegSmall) 578 buf = encodeNonsortingDecimalValue(uint64(-e), bNat, buf) 579 return append(b, buf...) 580 case !neg && e < 0: 581 b = append(b, decimalPosSmall) 582 buf = encodeNonsortingDecimalValue(uint64(-e), bNat, buf) 583 return append(b, buf...) 584 case !neg && e == 0: 585 b = append(b, decimalPosMedium) 586 buf = encodeNonsortingDecimalValueWithoutExp(bNat, buf) 587 return append(b, buf...) 588 case !neg && e > 0: 589 b = append(b, decimalPosLarge) 590 buf = encodeNonsortingDecimalValue(uint64(e), bNat, buf) 591 return append(b, buf...) 592 } 593 panic("unreachable") 594 } 595 596 // encodeNonsortingDecimalValue encodes the absolute value of a decimal's 597 // exponent and slice of digit bytes into buf, returning the populated buffer 598 // after encoding. The function first encodes the absolute value of a 599 // decimal's exponent as an unsigned varint. Following this, it copies the 600 // decimal's big-endian digits themselves into the buffer. 601 func encodeNonsortingDecimalValue(exp uint64, digits []big.Word, buf []byte) []byte { 602 // Encode the exponent using a Uvarint. 603 buf = EncodeUvarintAscending(buf, exp) 604 605 // Encode the digits into the end of the byte slice. 606 return copyWords(buf, digits) 607 } 608 609 func encodeNonsortingDecimalValueWithoutExp(digits []big.Word, buf []byte) []byte { 610 // Encode the digits into the end of the byte slice. 611 return copyWords(buf, digits) 612 } 613 614 // DecodeNonsortingDecimal returns the decoded decimal from buf encoded with 615 // EncodeNonsortingDecimal. buf is assumed to contain only the encoded decimal, 616 // as the function does not know from the encoding itself what the length 617 // of the encoded value is. 618 func DecodeNonsortingDecimal(buf []byte, tmp []byte) (apd.Decimal, error) { 619 var dec apd.Decimal 620 err := DecodeIntoNonsortingDecimal(&dec, buf, tmp) 621 return dec, err 622 } 623 624 // DecodeIntoNonsortingDecimal is like DecodeNonsortingDecimal, but it operates 625 // on the passed-in *apd.Decimal instead of producing a new one. 626 func DecodeIntoNonsortingDecimal(dec *apd.Decimal, buf []byte, tmp []byte) error { 627 *dec = apd.Decimal{} 628 switch buf[0] { 629 case decimalNaN: 630 dec.Form = apd.NaN 631 return nil 632 case decimalNegativeInfinity: 633 dec.Form = apd.Infinite 634 dec.Negative = true 635 return nil 636 case decimalInfinity: 637 dec.Form = apd.Infinite 638 return nil 639 case decimalZero: 640 return nil 641 } 642 643 dec.Form = apd.Finite 644 switch { 645 case buf[0] == decimalNegLarge: 646 if err := decodeNonsortingDecimalValue(dec, false, buf[1:], tmp); err != nil { 647 return err 648 } 649 dec.Negative = true 650 return nil 651 case buf[0] == decimalNegMedium: 652 decodeNonsortingDecimalValueWithoutExp(dec, buf[1:], tmp) 653 dec.Negative = true 654 return nil 655 case buf[0] == decimalNegSmall: 656 if err := decodeNonsortingDecimalValue(dec, true, buf[1:], tmp); err != nil { 657 return err 658 } 659 dec.Negative = true 660 return nil 661 case buf[0] == decimalPosSmall: 662 if err := decodeNonsortingDecimalValue(dec, true, buf[1:], tmp); err != nil { 663 return err 664 } 665 return nil 666 case buf[0] == decimalPosMedium: 667 decodeNonsortingDecimalValueWithoutExp(dec, buf[1:], tmp) 668 return nil 669 case buf[0] == decimalPosLarge: 670 if err := decodeNonsortingDecimalValue(dec, false, buf[1:], tmp); err != nil { 671 return err 672 } 673 return nil 674 default: 675 return errors.Errorf("unknown decimal prefix of the encoded byte slice: %q", buf) 676 } 677 } 678 679 func decodeNonsortingDecimalValue(dec *apd.Decimal, negExp bool, buf, tmp []byte) error { 680 // Decode the exponent. 681 buf, e, err := DecodeUvarintAscending(buf) 682 if err != nil { 683 return err 684 } 685 if negExp { 686 e = -e 687 } 688 689 bi := &dec.Coeff 690 bi.SetBytes(buf) 691 692 // Set the decimal's scale. 693 nDigits := int(apd.NumDigits(bi)) 694 exp := int(e) - nDigits 695 dec.Exponent = int32(exp) 696 return nil 697 } 698 699 func decodeNonsortingDecimalValueWithoutExp(dec *apd.Decimal, buf, tmp []byte) { 700 bi := &dec.Coeff 701 bi.SetBytes(buf) 702 703 // Set the decimal's scale. 704 nDigits := apd.NumDigits(bi) 705 dec.Exponent = -int32(nDigits) 706 } 707 708 // UpperBoundNonsortingDecimalSize returns the upper bound number of bytes 709 // that the decimal will need for the non-sorting encoding. 710 func UpperBoundNonsortingDecimalSize(d *apd.Decimal) int { 711 // Makeup of upper bound size: 712 // - 1 byte for the prefix 713 // - maxVarintSize for the exponent 714 // - WordLen for the big.Int bytes 715 return 1 + maxVarintSize + WordLen(d.Coeff.Bits()) 716 } 717 718 // upperBoundNonsortingDecimalUnscaledSize is the same as 719 // UpperBoundNonsortingDecimalSize but for a decimal with the given unscaled 720 // length. The upper bound here may not be as tight as the one returned by 721 // UpperBoundNonsortingDecimalSize. 722 func upperBoundNonsortingDecimalUnscaledSize(unscaledLen int) int { 723 // The number of digits needed to represent a base 10 number of length 724 // unscaledLen in base 2. 725 unscaledLenBase2 := float64(unscaledLen) * math.Log2(10) 726 unscaledLenBase2Words := math.Ceil(unscaledLenBase2 / 8 / float64(bigWordSize)) 727 unscaledLenWordRounded := int(unscaledLenBase2Words) * bigWordSize 728 // Makeup of upper bound size: 729 // - 1 byte for the prefix 730 // - maxVarintSize for the exponent 731 // - unscaledLenWordRounded for the big.Int bytes 732 return 1 + maxVarintSize + unscaledLenWordRounded 733 } 734 735 // Taken from math/big/arith.go. 736 const bigWordSize = int(unsafe.Sizeof(big.Word(0))) 737 738 // WordLen returns the size in bytes of the given array of Words. 739 func WordLen(nat []big.Word) int { 740 return len(nat) * bigWordSize 741 } 742 743 // copyWords was adapted from math/big/nat.go. It writes the value of 744 // nat into buf using big-endian encoding. len(buf) must be >= len(nat)*bigWordSize. 745 func copyWords(buf []byte, nat []big.Word) []byte { 746 // Omit leading zeros from the resulting byte slice, which is both 747 // safe and exactly what big.Int.Bytes() does. See big.nat.setBytes() 748 // and big.nat.norm() for how this is normalized on decoding. 749 leading := true 750 for w := len(nat) - 1; w >= 0; w-- { 751 d := nat[w] 752 for j := bigWordSize - 1; j >= 0; j-- { 753 by := byte(d >> (8 * big.Word(j))) 754 if by == 0 && leading { 755 continue 756 } 757 leading = false 758 buf = append(buf, by) 759 } 760 } 761 return buf 762 }