diff options
Diffstat (limited to 'libgo/go/strconv/ftoa.go')
-rw-r--r-- | libgo/go/strconv/ftoa.go | 160 |
1 files changed, 78 insertions, 82 deletions
diff --git a/libgo/go/strconv/ftoa.go b/libgo/go/strconv/ftoa.go index e1ea0a35038..692e3e40875 100644 --- a/libgo/go/strconv/ftoa.go +++ b/libgo/go/strconv/ftoa.go @@ -45,20 +45,30 @@ var float64info = floatInfo{52, 11, -1023} // Ftoa32(f) is not the same as Ftoa64(float32(f)), // because correct rounding and the number of digits // needed to identify f depend on the precision of the representation. -func FormatFloat(f float64, fmt byte, prec int, n int) string { - if n == 32 { - return genericFtoa(uint64(math.Float32bits(float32(f))), fmt, prec, &float32info) - } - return genericFtoa(math.Float64bits(f), fmt, prec, &float64info) +func FormatFloat(f float64, fmt byte, prec, bitSize int) string { + return string(genericFtoa(make([]byte, 0, max(prec+4, 24)), f, fmt, prec, bitSize)) } // 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, n int) []byte { - return append(dst, FormatFloat(f, fmt, prec, n)...) +func AppendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int) []byte { + return genericFtoa(dst, f, fmt, prec, bitSize) } -func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string { +func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte { + var bits uint64 + var flt *floatInfo + switch bitSize { + case 32: + bits = uint64(math.Float32bits(float32(val))) + flt = &float32info + case 64: + bits = math.Float64bits(val) + flt = &float64info + default: + panic("strconv: illegal AppendFloat/FormatFloat bitSize") + } + neg := bits>>(flt.expbits+flt.mantbits) != 0 exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1) mant := bits & (uint64(1)<<flt.mantbits - 1) @@ -66,13 +76,16 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string { switch exp { case 1<<flt.expbits - 1: // Inf, NaN - if mant != 0 { - return "NaN" - } - if neg { - return "-Inf" + var s string + switch { + case mant != 0: + s = "NaN" + case neg: + s = "-Inf" + default: + s = "+Inf" } - return "+Inf" + return append(dst, s...) case 0: // denormalized @@ -86,7 +99,7 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string { // Pick off easy binary format. if fmt == 'b' { - return fmtB(neg, mant, exp, flt) + return fmtB(dst, neg, mant, exp, flt) } // Create exact decimal representation. @@ -127,9 +140,9 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string { switch fmt { case 'e', 'E': - return fmtE(neg, d, prec, fmt) + return fmtE(dst, neg, d, prec, fmt) case 'f': - return fmtF(neg, d, prec) + return fmtF(dst, neg, d, prec) case 'g', 'G': // trailing fractional zeros in 'e' form will be trimmed. eprec := prec @@ -147,15 +160,16 @@ func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string { if prec > d.nd { prec = d.nd } - return fmtE(neg, d, prec-1, fmt+'e'-'g') + return fmtE(dst, neg, d, prec-1, fmt+'e'-'g') } if prec > d.dp { prec = d.nd } - return fmtF(neg, d, max(prec-d.dp, 0)) + return fmtF(dst, neg, d, max(prec-d.dp, 0)) } - return "%" + string(fmt) + // unknown format + return append(dst, '%', fmt) } // Round d (= mant * 2^exp) to the shortest number of digits @@ -250,121 +264,103 @@ func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) { } // %e: -d.ddddde±dd -func fmtE(neg bool, d *decimal, prec int, fmt byte) string { - buf := make([]byte, 3+max(prec, 0)+30) // "-0." + prec digits + exp - w := 0 // write index - +func fmtE(dst []byte, neg bool, d *decimal, prec int, fmt byte) []byte { // sign if neg { - buf[w] = '-' - w++ + dst = append(dst, '-') } // first digit - if d.nd == 0 { - buf[w] = '0' - } else { - buf[w] = d.d[0] + ch := byte('0') + if d.nd != 0 { + ch = d.d[0] } - w++ + dst = append(dst, ch) // .moredigits if prec > 0 { - buf[w] = '.' - w++ - for i := 0; i < prec; i++ { - if 1+i < d.nd { - buf[w] = d.d[1+i] - } else { - buf[w] = '0' + dst = append(dst, '.') + for i := 1; i <= prec; i++ { + ch = '0' + if i < d.nd { + ch = d.d[i] } - w++ + dst = append(dst, ch) } } // e± - buf[w] = fmt - w++ + dst = append(dst, fmt) exp := d.dp - 1 if d.nd == 0 { // special case: 0 has exponent 0 exp = 0 } if exp < 0 { - buf[w] = '-' + ch = '-' exp = -exp } else { - buf[w] = '+' + ch = '+' } - w++ + dst = append(dst, ch) // dddd - // count digits - n := 0 - for e := exp; e > 0; e /= 10 { - n++ + var buf [3]byte + i := len(buf) + for exp >= 10 { + i-- + buf[i] = byte(exp%10 + '0') + exp /= 10 } - // leading zeros - for i := n; i < 2; i++ { - buf[w] = '0' - w++ - } - // digits - w += n - n = 0 - for e := exp; e > 0; e /= 10 { - n++ - buf[w-n] = byte(e%10 + '0') + // exp < 10 + i-- + buf[i] = byte(exp + '0') + + // leading zeroes + if i > len(buf)-2 { + i-- + buf[i] = '0' } - return string(buf[0:w]) + return append(dst, buf[i:]...) } // %f: -ddddddd.ddddd -func fmtF(neg bool, d *decimal, prec int) string { - buf := make([]byte, 1+max(d.dp, 1)+1+max(prec, 0)) - w := 0 - +func fmtF(dst []byte, neg bool, d *decimal, prec int) []byte { // sign if neg { - buf[w] = '-' - w++ + dst = append(dst, '-') } // integer, padded with zeros as needed. if d.dp > 0 { var i int for i = 0; i < d.dp && i < d.nd; i++ { - buf[w] = d.d[i] - w++ + dst = append(dst, d.d[i]) } for ; i < d.dp; i++ { - buf[w] = '0' - w++ + dst = append(dst, '0') } } else { - buf[w] = '0' - w++ + dst = append(dst, '0') } // fraction if prec > 0 { - buf[w] = '.' - w++ + dst = append(dst, '.') for i := 0; i < prec; i++ { - if d.dp+i < 0 || d.dp+i >= d.nd { - buf[w] = '0' - } else { - buf[w] = d.d[d.dp+i] + ch := byte('0') + if j := d.dp + i; 0 <= j && j < d.nd { + ch = d.d[j] } - w++ + dst = append(dst, ch) } } - return string(buf[0:w]) + return dst } // %b: -ddddddddp+ddd -func fmtB(neg bool, mant uint64, exp int, flt *floatInfo) string { +func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte { var buf [50]byte w := len(buf) exp -= int(flt.mantbits) @@ -395,7 +391,7 @@ func fmtB(neg bool, mant uint64, exp int, flt *floatInfo) string { w-- buf[w] = '-' } - return string(buf[w:]) + return append(dst, buf[w:]...) } func max(a, b int) int { |