summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/text/internal/number/format.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/text/internal/number/format.go')
-rwxr-xr-xvendor/golang.org/x/text/internal/number/format.go169
1 files changed, 112 insertions, 57 deletions
diff --git a/vendor/golang.org/x/text/internal/number/format.go b/vendor/golang.org/x/text/internal/number/format.go
index 70ddf7df1..533a85a28 100755
--- a/vendor/golang.org/x/text/internal/number/format.go
+++ b/vendor/golang.org/x/text/internal/number/format.go
@@ -131,23 +131,87 @@ func (f *Formatter) Format(dst []byte, d *Decimal) []byte {
return result
}
-// appendDecimal appends a formatted number to dst. It returns two possible
-// insertion points for padding.
-func appendDecimal(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre, preSuf int) {
- if dst, ok := f.renderSpecial(dst, d); ok {
- return dst, 0, len(dst)
+// TODO: just return visible digits.
+func decimalVisibleDigits(f *Formatter, d *Decimal) Decimal {
+ if d.NaN || d.Inf {
+ return *d
}
n := d.normalize()
if maxSig := int(f.MaxSignificantDigits); maxSig > 0 {
+ // TODO: really round to zero?
n.round(ToZero, maxSig)
}
digits := n.Digits
exp := n.Exp
exp += int32(f.Pattern.DigitShift)
+ // Cap integer digits. Remove *most-significant* digits.
+ if f.MaxIntegerDigits > 0 {
+ if p := int(exp) - int(f.MaxIntegerDigits); p > 0 {
+ if p > len(digits) {
+ p = len(digits)
+ }
+ if digits = digits[p:]; len(digits) == 0 {
+ exp = 0
+ } else {
+ exp -= int32(p)
+ }
+ // Strip leading zeros.
+ for len(digits) > 0 && digits[0] == 0 {
+ digits = digits[1:]
+ exp--
+ }
+ }
+ }
+
+ // Rounding usually is done by convert, but we don't rely on it.
+ numFrac := len(digits) - int(exp)
+ if f.MaxSignificantDigits == 0 && int(f.MaxFractionDigits) < numFrac {
+ p := int(exp) + int(f.MaxFractionDigits)
+ if p <= 0 {
+ p = 0
+ } else if p >= len(digits) {
+ p = len(digits)
+ }
+ digits = digits[:p] // TODO: round
+ }
+
+ // set End (trailing zeros)
+ n.End = int32(len(digits))
+ if len(digits) == 0 {
+ if f.MinFractionDigits > 0 {
+ n.End = int32(f.MinFractionDigits)
+ }
+ if p := int32(f.MinSignificantDigits) - 1; p > n.End {
+ n.End = p
+ }
+ } else {
+ if end := exp + int32(f.MinFractionDigits); end > n.End {
+ n.End = end
+ }
+ if n.End < int32(f.MinSignificantDigits) {
+ n.End = int32(f.MinSignificantDigits)
+ }
+ }
+ n.Digits = digits
+ n.Exp = exp
+ return n
+}
+
+// appendDecimal appends a formatted number to dst. It returns two possible
+// insertion points for padding.
+func appendDecimal(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre, preSuf int) {
+ if dst, ok := f.renderSpecial(dst, d); ok {
+ return dst, 0, len(dst)
+ }
+ n := decimalVisibleDigits(f, d)
+ digits := n.Digits
+ exp := n.Exp
+
// Split in integer and fraction part.
var intDigits, fracDigits []byte
- var numInt, numFrac int
+ numInt := 0
+ numFrac := int(n.End - n.Exp)
if exp > 0 {
numInt = int(exp)
if int(exp) >= len(digits) { // ddddd | ddddd00
@@ -155,39 +219,9 @@ func appendDecimal(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre, pre
} else { // ddd.dd
intDigits = digits[:exp]
fracDigits = digits[exp:]
- numFrac = len(fracDigits)
}
} else {
fracDigits = digits
- numFrac = -int(exp) + len(digits)
- }
- // Cap integer digits. Remove *most-significant* digits.
- if f.MaxIntegerDigits > 0 && numInt > int(f.MaxIntegerDigits) {
- offset := numInt - int(f.MaxIntegerDigits)
- if offset > len(intDigits) {
- numInt = 0
- intDigits = nil
- } else {
- numInt = int(f.MaxIntegerDigits)
- intDigits = intDigits[offset:]
- // for keeping track of significant digits
- digits = digits[offset:]
- }
- // Strip leading zeros. Resulting number of digits is significant digits.
- for len(intDigits) > 0 && intDigits[0] == 0 {
- intDigits = intDigits[1:]
- digits = digits[1:]
- numInt--
- }
- }
- if f.MaxSignificantDigits == 0 && int(f.MaxFractionDigits) < numFrac {
- if extra := numFrac - int(f.MaxFractionDigits); extra > len(fracDigits) {
- numFrac = 0
- fracDigits = nil
- } else {
- numFrac = int(f.MaxFractionDigits)
- fracDigits = fracDigits[:len(fracDigits)-extra]
- }
}
neg := d.Neg
@@ -220,43 +254,41 @@ func appendDecimal(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre, pre
}
}
- trailZero := int(f.MinFractionDigits) - numFrac
- if d := int(f.MinSignificantDigits) - len(digits); d > 0 && d > trailZero {
- trailZero = d
- }
- if numFrac > 0 || trailZero > 0 || f.Flags&AlwaysDecimalSeparator != 0 {
+ if numFrac > 0 || f.Flags&AlwaysDecimalSeparator != 0 {
dst = append(dst, f.Symbol(SymDecimal)...)
}
// Add leading zeros
- for i := numFrac - len(fracDigits); i > 0; i-- {
+ i = 0
+ for n := -int(n.Exp); i < n; i++ {
dst = f.AppendDigit(dst, 0)
}
- i = 0
- for ; i < len(fracDigits); i++ {
- dst = f.AppendDigit(dst, fracDigits[i])
+ for _, d := range fracDigits {
+ i++
+ dst = f.AppendDigit(dst, d)
}
- for ; trailZero > 0; trailZero-- {
+ for ; i < numFrac; i++ {
dst = f.AppendDigit(dst, 0)
}
return appendAffix(dst, f, suffix, neg), savedLen, len(dst)
}
-// appendScientific appends a formatted number to dst. It returns two possible
-// insertion points for padding.
-func appendScientific(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre, preSuf int) {
- if dst, ok := f.renderSpecial(dst, d); ok {
- return dst, 0, 0
+func scientificVisibleDigits(f *Formatter, d *Decimal) Decimal {
+ if d.NaN || d.Inf {
+ return *d
}
- // Significant digits are transformed by parser for scientific notation and
- // do not need to be handled here.
+ n := d.normalize()
+
+ // Significant digits are transformed by the parser for scientific notation
+ // and do not need to be handled here.
maxInt, numInt := int(f.MaxIntegerDigits), int(f.MinIntegerDigits)
if numInt == 0 {
numInt = 1
}
maxSig := int(f.MaxFractionDigits) + numInt
minSig := int(f.MinFractionDigits) + numInt
- n := d.normalize()
+
if maxSig > 0 {
+ // TODO: really round to zero?
n.round(ToZero, maxSig)
}
digits := n.Digits
@@ -282,6 +314,30 @@ func appendScientific(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre,
} else {
exp -= int32(numInt)
}
+
+ n.Comma = uint8(numInt)
+ n.End = int32(len(digits))
+ if n.End < int32(minSig) {
+ n.End = int32(minSig)
+ }
+ n.Digits = digits
+ n.Exp = exp
+ return n
+}
+
+// appendScientific appends a formatted number to dst. It returns two possible
+// insertion points for padding.
+func appendScientific(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre, preSuf int) {
+ if dst, ok := f.renderSpecial(dst, d); ok {
+ return dst, 0, 0
+ }
+ // n := d.normalize()
+ n := scientificVisibleDigits(f, d)
+ digits := n.Digits
+ exp := n.Exp
+ numInt := int(n.Comma)
+ numFrac := int(n.End) - int(n.Comma)
+
var intDigits, fracDigits []byte
if numInt <= len(digits) {
intDigits = digits[:numInt]
@@ -308,15 +364,14 @@ func appendScientific(dst []byte, f *Formatter, d *Decimal) (b []byte, postPre,
}
}
- trailZero := minSig - numInt - len(fracDigits)
- if len(fracDigits) > 0 || trailZero > 0 || f.Flags&AlwaysDecimalSeparator != 0 {
+ if numFrac > 0 || f.Flags&AlwaysDecimalSeparator != 0 {
dst = append(dst, f.Symbol(SymDecimal)...)
}
i = 0
for ; i < len(fracDigits); i++ {
dst = f.AppendDigit(dst, fracDigits[i])
}
- for ; trailZero > 0; trailZero-- {
+ for ; i < numFrac; i++ {
dst = f.AppendDigit(dst, 0)
}