ShortestDecimal stores in d the shortest decimal representation of f which belongs to the open interval (lower, upper), where f is supposed to lie. It returns false whenever the result is unsure. The implementation uses the Grisu3 algorithm.
(d *decimalSlice, lower, upper *extFloat)
| 530 | // to lie. It returns false whenever the result is unsure. The implementation |
| 531 | // uses the Grisu3 algorithm. |
| 532 | func (f *extFloat) ShortestDecimal(d *decimalSlice, lower, upper *extFloat) bool { |
| 533 | if f.mant == 0 { |
| 534 | d.nd = 0 |
| 535 | d.dp = 0 |
| 536 | d.neg = f.neg |
| 537 | return true |
| 538 | } |
| 539 | if f.exp == 0 && *lower == *f && *lower == *upper { |
| 540 | // an exact integer. |
| 541 | var buf [24]byte |
| 542 | n := len(buf) - 1 |
| 543 | for v := f.mant; v > 0; { |
| 544 | v1 := v / 10 |
| 545 | v -= 10 * v1 |
| 546 | buf[n] = byte(v + '0') |
| 547 | n-- |
| 548 | v = v1 |
| 549 | } |
| 550 | nd := len(buf) - n - 1 |
| 551 | for i := 0; i < nd; i++ { |
| 552 | d.d[i] = buf[n+1+i] |
| 553 | } |
| 554 | d.nd, d.dp = nd, nd |
| 555 | for d.nd > 0 && d.d[d.nd-1] == '0' { |
| 556 | d.nd-- |
| 557 | } |
| 558 | if d.nd == 0 { |
| 559 | d.dp = 0 |
| 560 | } |
| 561 | d.neg = f.neg |
| 562 | return true |
| 563 | } |
| 564 | upper.Normalize() |
| 565 | // Uniformize exponents. |
| 566 | if f.exp > upper.exp { |
| 567 | f.mant <<= uint(f.exp - upper.exp) |
| 568 | f.exp = upper.exp |
| 569 | } |
| 570 | if lower.exp > upper.exp { |
| 571 | lower.mant <<= uint(lower.exp - upper.exp) |
| 572 | lower.exp = upper.exp |
| 573 | } |
| 574 | |
| 575 | exp10 := frexp10Many(lower, f, upper) |
| 576 | // Take a safety margin due to rounding in frexp10Many, but we lose precision. |
| 577 | upper.mant++ |
| 578 | lower.mant-- |
| 579 | |
| 580 | // The shortest representation of f is either rounded up or down, but |
| 581 | // in any case, it is a truncation of upper. |
| 582 | shift := uint(-upper.exp) |
| 583 | integer := uint32(upper.mant >> shift) |
| 584 | fraction := upper.mant - (uint64(integer) << shift) |
| 585 | |
| 586 | // How far we can go down from upper until the result is wrong. |
| 587 | allowance := upper.mant - lower.mant |
| 588 | // How far we should go to get a very precise result. |
| 589 | targetDiff := upper.mant - f.mant |
no test coverage detected