]> Cypherpunks repositories - gostls13.git/commitdiff
math/big: build Float.Format on top of Float.Append
authorRobert Griesemer <gri@golang.org>
Fri, 30 Jan 2015 23:57:38 +0000 (15:57 -0800)
committerRobert Griesemer <gri@golang.org>
Tue, 3 Feb 2015 18:43:51 +0000 (18:43 +0000)
Change-Id: I444eec24467f827caa5c88a1c5ae5bce92508b98
Reviewed-on: https://go-review.googlesource.com/3750
Reviewed-by: Alan Donovan <adonovan@google.com>
src/math/big/float.go
src/math/big/float_test.go
src/math/big/floatconv.go

index 7047a6d996af7e40f48198988b59385edee615ab..1c3fcb5f7429f6962d1d832c76466203fc5fe0c9 100644 (file)
@@ -176,7 +176,7 @@ func (x *Float) validate() {
        const msb = 1 << (_W - 1)
        m := len(x.mant)
        if x.mant[m-1]&msb == 0 {
-               panic(fmt.Sprintf("msb not set in last word %#x of %s", x.mant[m-1], x.pstring()))
+               panic(fmt.Sprintf("msb not set in last word %#x of %s", x.mant[m-1], x.Format('p', 0)))
        }
        if x.prec <= 0 {
                panic(fmt.Sprintf("invalid precision %d", x.prec))
index 3281f2745aadbd4ac4bb46464e24b63501406447..ec67a6d6065640abfbd89413e99d36ac00a408ed 100644 (file)
@@ -205,7 +205,7 @@ func TestFloatSetUint64(t *testing.T) {
        } {
                f := new(Float).SetUint64(want)
                if got := f.Uint64(); got != want {
-                       t.Errorf("got %d (%s); want %d", got, f.pstring(), want)
+                       t.Errorf("got %d (%s); want %d", got, f.Format('p', 0), want)
                }
        }
 }
@@ -227,7 +227,7 @@ func TestFloatSetInt64(t *testing.T) {
                        }
                        f := new(Float).SetInt64(want)
                        if got := f.Int64(); got != want {
-                               t.Errorf("got %d (%s); want %d", got, f.pstring(), want)
+                               t.Errorf("got %d (%s); want %d", got, f.Format('p', 0), want)
                        }
                }
        }
@@ -251,7 +251,7 @@ func TestFloatSetFloat64(t *testing.T) {
                        }
                        f := new(Float).SetFloat64(want)
                        if got, _ := f.Float64(); got != want {
-                               t.Errorf("got %g (%s); want %g", got, f.pstring(), want)
+                               t.Errorf("got %g (%s); want %g", got, f.Format('p', 0), want)
                        }
                }
        }
@@ -677,7 +677,7 @@ func TestFromBits(t *testing.T) {
                {append([]int{2, 1, 0} /* 7 */, []int{3, 1} /* 10 */ ...), "0x.88p5" /* 17 */},
        } {
                f := fromBits(test.bits...)
-               if got := f.pstring(); got != test.want {
+               if got := f.Format('p', 0); got != test.want {
                        t.Errorf("setBits(%v) = %s; want %s", test.bits, got, test.want)
                }
        }
index 06bbdbcb023209190a4a9caae689e2d896806e59..f50a3a5c72adefa537e44ecf101220ab5958c4d6 100644 (file)
@@ -7,9 +7,9 @@
 package big
 
 import (
-       "bytes"
        "fmt"
        "io"
+       "strconv"
        "strings"
 )
 
@@ -184,13 +184,20 @@ func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b i
 //
 // BUG(gri) Currently, Format only accepts the 'b' and 'p' format.
 func (x *Float) Format(format byte, prec int) string {
+       const extra = 10 // TODO(gri) determine a good/better vaue here
+       return string(x.Append(make([]byte, 0, prec+extra), format, prec))
+}
+
+// Append appends the string form of the floating-point number x,
+// as generated by x.Format, to buf and returns the extended buffer.
+func (x *Float) Append(buf []byte, format byte, prec int) []byte {
        switch format {
        case 'b':
-               return x.bstring()
+               return x.bstring(buf)
        case 'p':
-               return x.pstring()
+               return x.pstring(buf)
        }
-       return fmt.Sprintf(`%%!c(%s)`, format, x.pstring())
+       return append(buf, fmt.Sprintf(`%%!c`, format)...)
 }
 
 // BUG(gri): Currently, String uses the 'p' (rather than 'g') format.
@@ -204,17 +211,18 @@ func (x *Float) String() string {
 // (a strconv 'p' formatted float value can only be interpreted correctly
 // if the bias is known; i.e., we must know if it's a 32bit or 64bit number).
 
-// bstring returns x as a string in the format ["-"] mantissa "p" exponent
-// with a decimal mantissa and a binary exponent, or ["-"] "0" if x is zero.
+// bstring appends the string of x in the format ["-"] mantissa "p" exponent
+// with a decimal mantissa and a binary exponent, or ["-"] "0" if x is zero,
+// and returns the extended buffer.
 // The mantissa is normalized such that is uses x.Precision() bits in binary
 // representation.
-func (x *Float) bstring() string {
+func (x *Float) bstring(buf []byte) []byte {
        // TODO(gri) handle Inf
+       if x.neg {
+               buf = append(buf, '-')
+       }
        if len(x.mant) == 0 {
-               if x.neg {
-                       return "-0"
-               }
-               return "0"
+               return append(buf, '0')
        }
        // x != 0
        // normalize mantissa
@@ -223,34 +231,27 @@ func (x *Float) bstring() string {
        if t > 0 {
                m = nat(nil).shr(m, t)
        }
-       var buf bytes.Buffer
-       if x.neg {
-               buf.WriteByte('-')
-       }
-       buf.WriteString(m.decimalString())
-       fmt.Fprintf(&buf, "p%d", x.exp)
-       return buf.String()
+       buf = append(buf, m.decimalString()...)
+       buf = append(buf, 'p')
+       return strconv.AppendInt(buf, int64(x.exp), 10)
 }
 
-// pstring returns x as a string in the format ["-"] "0x." mantissa "p" exponent
-// with a hexadecimal mantissa and a binary exponent, or ["-"] "0" if x is zero.
+// pstring appends the string of x in the format ["-"] "0x." mantissa "p" exponent
+// with a hexadecimal mantissa and a binary exponent, or ["-"] "0" if x is zero,
+// ad returns the extended buffer.
 // The mantissa is normalized such that 0.5 <= 0.mantissa < 1.0.
-func (x *Float) pstring() string {
+func (x *Float) pstring(buf []byte) []byte {
        // TODO(gri) handle Inf
+       if x.neg {
+               buf = append(buf, '-')
+       }
        if len(x.mant) == 0 {
-               if x.neg {
-                       return "-0"
-               }
-               return "0"
+               return append(buf, '0')
        }
        // x != 0
        // mantissa is stored in normalized form
-       var buf bytes.Buffer
-       if x.neg {
-               buf.WriteByte('-')
-       }
-       buf.WriteString("0x.")
-       buf.WriteString(strings.TrimRight(x.mant.hexString(), "0"))
-       fmt.Fprintf(&buf, "p%d", x.exp)
-       return buf.String()
+       buf = append(buf, "0x."...)
+       buf = append(buf, strings.TrimRight(x.mant.hexString(), "0")...)
+       buf = append(buf, 'p')
+       return strconv.AppendInt(buf, int64(x.exp), 10)
 }