summaryrefslogtreecommitdiff
path: root/libgo/go/strconv/ftoa.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/strconv/ftoa.go')
-rw-r--r--libgo/go/strconv/ftoa.go108
1 files changed, 44 insertions, 64 deletions
diff --git a/libgo/go/strconv/ftoa.go b/libgo/go/strconv/ftoa.go
index 1a9c41b85a8..468c37fafb9 100644
--- a/libgo/go/strconv/ftoa.go
+++ b/libgo/go/strconv/ftoa.go
@@ -47,7 +47,7 @@ func FormatFloat(f float64, fmt byte, prec, bitSize int) string {
// AppendFloat appends the string form of the floating-point number f,
// as generated by FormatFloat, to dst and returns the extended buffer.
-func AppendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte {
+func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte {
return genericFtoa(dst, f, fmt, prec, bitSize)
}
@@ -119,7 +119,7 @@ func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte {
// Precision for shortest representation mode.
switch fmt {
case 'e', 'E':
- prec = digs.nd - 1
+ prec = max(digs.nd-1, 0)
case 'f':
prec = max(digs.nd-digs.dp, 0)
case 'g', 'G':
@@ -223,9 +223,8 @@ func formatDigits(dst []byte, shortest bool, neg bool, digs decimalSlice, prec i
return append(dst, '%', fmt)
}
-// Round d (= mant * 2^exp) to the shortest number of digits
-// that will let the original floating point value be precisely
-// reconstructed. Size is original floating point size (64 or 32).
+// roundShortest rounds d (= mant * 2^exp) to the shortest number of digits
+// that will let the original floating point value be precisely reconstructed.
func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
// If mantissa is zero, the number is zero; stop now.
if mant == 0 {
@@ -348,14 +347,13 @@ func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
if prec > 0 {
dst = append(dst, '.')
i := 1
- m := d.nd + prec + 1 - max(d.nd, prec+1)
- for i < m {
- dst = append(dst, d.d[i])
- i++
+ m := min(d.nd, prec+1)
+ if i < m {
+ dst = append(dst, d.d[i:m]...)
+ i = m
}
- for i <= prec {
+ for ; i <= prec; i++ {
dst = append(dst, '0')
- i++
}
}
@@ -373,27 +371,16 @@ func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
}
dst = append(dst, ch)
- // dddd
- var buf [3]byte
- i := len(buf)
- for exp >= 10 {
- i--
- buf[i] = byte(exp%10 + '0')
- exp /= 10
+ // dd or ddd
+ switch {
+ case exp < 10:
+ dst = append(dst, '0', byte(exp)+'0')
+ case exp < 100:
+ dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0')
+ default:
+ dst = append(dst, byte(exp/100)+'0', byte(exp/10)%10+'0', byte(exp%10)+'0')
}
- // exp < 10
- i--
- buf[i] = byte(exp + '0')
- switch i {
- case 0:
- dst = append(dst, buf[0], buf[1], buf[2])
- case 1:
- dst = append(dst, buf[1], buf[2])
- case 2:
- // leading zeroes
- dst = append(dst, '0', buf[2])
- }
return dst
}
@@ -406,11 +393,9 @@ func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
// integer, padded with zeros as needed.
if d.dp > 0 {
- var i int
- for i = 0; i < d.dp && i < d.nd; i++ {
- dst = append(dst, d.d[i])
- }
- for ; i < d.dp; i++ {
+ m := min(d.nd, d.dp)
+ dst = append(dst, d.d[:m]...)
+ for ; m < d.dp; m++ {
dst = append(dst, '0')
}
} else {
@@ -432,39 +417,34 @@ func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
return dst
}
-// %b: -ddddddddp+ddd
+// %b: -ddddddddp±ddd
func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
- var buf [50]byte
- w := len(buf)
- exp -= int(flt.mantbits)
- esign := byte('+')
- if exp < 0 {
- esign = '-'
- exp = -exp
- }
- n := 0
- for exp > 0 || n < 1 {
- n++
- w--
- buf[w] = byte(exp%10 + '0')
- exp /= 10
+ // sign
+ if neg {
+ dst = append(dst, '-')
}
- w--
- buf[w] = esign
- w--
- buf[w] = 'p'
- n = 0
- for mant > 0 || n < 1 {
- n++
- w--
- buf[w] = byte(mant%10 + '0')
- mant /= 10
+
+ // mantissa
+ dst, _ = formatBits(dst, mant, 10, false, true)
+
+ // p
+ dst = append(dst, 'p')
+
+ // ±exponent
+ exp -= int(flt.mantbits)
+ if exp >= 0 {
+ dst = append(dst, '+')
}
- if neg {
- w--
- buf[w] = '-'
+ dst, _ = formatBits(dst, uint64(exp), 10, exp < 0, true)
+
+ return dst
+}
+
+func min(a, b int) int {
+ if a < b {
+ return a
}
- return append(dst, buf[w:]...)
+ return b
}
func max(a, b int) int {