internal/number: factor out code

for implementers of Convert (down the line)

removed scale and precision while at it

Change-Id: I0a7ef49d63e7042cd8b3602d56dd3cc472ad328b
Reviewed-on: https://go-review.googlesource.com/60710
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/internal/number/decimal.go b/internal/number/decimal.go
index 221a8b1..ac2098d 100644
--- a/internal/number/decimal.go
+++ b/internal/number/decimal.go
@@ -412,21 +412,11 @@
 	//   Something like this would work:
 	//   AppendDigits(dst []byte, x float64, base, size, prec int) (digits []byte, exp, accuracy int)
 	if r.Mode == ToNearestEven {
-		// We can't round if limitations are placed on both the fraction and
-		// significant digits.
-		if r.MaxFractionDigits == 0 && r.MaxSignificantDigits > 0 {
-			prec = int(r.MaxSignificantDigits)
-		} else if r.isScientific() {
-			if r.MaxIntegerDigits == 1 && (r.MaxSignificantDigits == 0 ||
-				int(r.MaxFractionDigits+1) == int(r.MaxSignificantDigits)) {
-				verb = 'e'
-				// Note: don't add DigitShift: it is only used for decimals.
-				prec = int(r.MaxFractionDigits)
-				prec += int(r.DigitShift)
-			}
-		} else if r.MaxFractionDigits > 0 && r.MaxSignificantDigits == 0 {
+		if n := r.RoundSignificantDigits(); n >= 0 {
+			prec = n
+		} else if n = r.RoundFractionDigits(); n >= 0 {
+			prec = n
 			verb = 'f'
-			prec = int(r.MaxFractionDigits) + int(r.DigitShift)
 		}
 	}
 
diff --git a/internal/number/pattern.go b/internal/number/pattern.go
index 2764cd2..eebaafd 100644
--- a/internal/number/pattern.go
+++ b/internal/number/pattern.go
@@ -77,15 +77,33 @@
 	MinExponentDigits uint8
 }
 
-func (r *RoundingContext) scale() int {
-	// scale is 0 when precision is set.
-	if r.MaxSignificantDigits != 0 {
-		return 0
+// RoundSignificantDigits returns the number of significant digits an
+// implementation of Convert may round to or n < 0 if there is no maximum or
+// a maximum is not recommended.
+func (r *RoundingContext) RoundSignificantDigits() (n int) {
+	if r.MaxFractionDigits == 0 && r.MaxSignificantDigits > 0 {
+		return int(r.MaxSignificantDigits)
+	} else if r.isScientific() && r.MaxIntegerDigits == 1 {
+		if r.MaxSignificantDigits == 0 ||
+			int(r.MaxFractionDigits+1) == int(r.MaxSignificantDigits) {
+			// Note: don't add DigitShift: it is only used for decimals.
+			return int(r.MaxFractionDigits) + 1
+		}
 	}
-	return int(r.MaxFractionDigits)
+	return -1
 }
 
-func (r *RoundingContext) precision() int { return int(r.MaxSignificantDigits) }
+// RoundFractionDigits returns the number of fraction digits an implementation
+// of Convert may round to or n < 0 if there is no maximum or a maximum is not
+// recommended.
+func (r *RoundingContext) RoundFractionDigits() (n int) {
+	if r.MinExponentDigits == 0 &&
+		r.MaxSignificantDigits == 0 &&
+		r.MaxFractionDigits >= 0 {
+		return int(r.MaxFractionDigits) + int(r.DigitShift)
+	}
+	return -1
+}
 
 // SetScale fixes the RoundingContext to a fixed number of fraction digits.
 func (r *RoundingContext) SetScale(scale int) {