MCPcopy
hub / github.com/pquerna/ffjson / ShortestDecimal

Method ShortestDecimal

fflib/v1/extfloat.go:532–639  ·  view source on GitHub ↗

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)

Source from the content-addressed store, hash-verified

530// to lie. It returns false whenever the result is unsure. The implementation
531// uses the Grisu3 algorithm.
532func (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

Callers 1

AppendFloatFunction · 0.95

Calls 3

frexp10ManyFunction · 0.70
adjustLastDigitFunction · 0.70
NormalizeMethod · 0.45

Tested by

no test coverage detected