]> Cypherpunks repositories - gostls13.git/commitdiff
math/big: fix %b format so it matches strconf %b format for non-zero values
authorRobert Griesemer <gri@golang.org>
Tue, 3 Feb 2015 23:13:26 +0000 (15:13 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 4 Feb 2015 21:07:37 +0000 (21:07 +0000)
(For zero values the strconv %b format prints the bias-adjusted exponent;
there's no bias in Float.)

Change-Id: I6f4dda9c3a50d02eac375cfe2c927c1540aae865
Reviewed-on: https://go-review.googlesource.com/3841
Reviewed-by: Alan Donovan <adonovan@google.com>
src/math/big/floatconv.go
src/math/big/floatconv_test.go

index a1b234f144e31742605e9c409c285c06a4177781..06c1f144711060286f1d4e17d6f8cb93bf1c745c 100644 (file)
@@ -205,12 +205,6 @@ func (x *Float) String() string {
        return x.Format('p', 0)
 }
 
-// TODO(gri) The 'b' and 'p' formats have different meanings here than
-// in strconv: in strconv, the printed exponent is the biased (hardware)
-// exponent; here it is the unbiased exponent. Decide what to do.
-// (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 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.
@@ -233,7 +227,11 @@ func (x *Float) bstring(buf []byte) []byte {
        }
        buf = append(buf, m.decimalString()...)
        buf = append(buf, 'p')
-       return strconv.AppendInt(buf, int64(x.exp), 10)
+       e := int64(x.exp) - int64(x.prec)
+       if e >= 0 {
+               buf = append(buf, '+')
+       }
+       return strconv.AppendInt(buf, e, 10)
 }
 
 // pstring appends the string of x in the format ["-"] "0x." mantissa "p" exponent
index 83ea1d60571acde0268bf748d134b4230b64db44..0e8bfb39ab329f8fd38635bc8bb75342632b06af 100644 (file)
@@ -9,55 +9,53 @@ import (
        "testing"
 )
 
-var floatSetFloat64StringTests = []struct {
-       s string
-       x float64
-}{
-       {"0", 0},
-       {"-0", -0},
-       {"+0", 0},
-       {"1", 1},
-       {"-1", -1},
-       {"+1", 1},
-       {"1.234", 1.234},
-       {"-1.234", -1.234},
-       {"+1.234", 1.234},
-       {".1", 0.1},
-       {"1.", 1},
-       {"+1.", 1},
-
-       {"0e100", 0},
-       {"-0e+100", 0},
-       {"+0e-100", 0},
-       {"0E100", 0},
-       {"-0E+100", 0},
-       {"+0E-100", 0},
-       {"0p100", 0},
-       {"-0p+100", 0},
-       {"+0p-100", 0},
+func TestFloatSetFloat64String(t *testing.T) {
+       for _, test := range []struct {
+               s string
+               x float64
+       }{
+               {"0", 0},
+               {"-0", -0},
+               {"+0", 0},
+               {"1", 1},
+               {"-1", -1},
+               {"+1", 1},
+               {"1.234", 1.234},
+               {"-1.234", -1.234},
+               {"+1.234", 1.234},
+               {".1", 0.1},
+               {"1.", 1},
+               {"+1.", 1},
 
-       {"1.e10", 1e10},
-       {"1e+10", 1e10},
-       {"+1e-10", 1e-10},
-       {"1E10", 1e10},
-       {"1.E+10", 1e10},
-       {"+1E-10", 1e-10},
-       {"1p10", 1 << 10},
-       {"1p+10", 1 << 10},
-       {"+1.p-10", 1.0 / (1 << 10)},
+               {"0e100", 0},
+               {"-0e+100", 0},
+               {"+0e-100", 0},
+               {"0E100", 0},
+               {"-0E+100", 0},
+               {"+0E-100", 0},
+               {"0p100", 0},
+               {"-0p+100", 0},
+               {"+0p-100", 0},
 
-       {"-687436.79457e-245", -687436.79457e-245},
-       {"-687436.79457E245", -687436.79457e245},
-       {"1024.p-12", 0.25},
-       {"-1.p10", -1024},
-       {"0.25p2", 1},
+               {"1.e10", 1e10},
+               {"1e+10", 1e10},
+               {"+1e-10", 1e-10},
+               {"1E10", 1e10},
+               {"1.E+10", 1e10},
+               {"+1E-10", 1e-10},
+               {"1p10", 1 << 10},
+               {"1p+10", 1 << 10},
+               {"+1.p-10", 1.0 / (1 << 10)},
 
-       {".0000000000000000000000000000000000000001", 1e-40},
-       {"+10000000000000000000000000000000000000000e-0", 1e40},
-}
+               {"-687436.79457e-245", -687436.79457e-245},
+               {"-687436.79457E245", -687436.79457e245},
+               {"1024.p-12", 0.25},
+               {"-1.p10", -1024},
+               {"0.25p2", 1},
 
-func TestFloatSetFloat64String(t *testing.T) {
-       for _, test := range floatSetFloat64StringTests {
+               {".0000000000000000000000000000000000000001", 1e-40},
+               {"+10000000000000000000000000000000000000000e-0", 1e40},
+       } {
                var x Float
                x.prec = 53 // TODO(gri) find better solution
                _, ok := x.SetString(test.s)
@@ -82,8 +80,9 @@ func TestFloatFormat(t *testing.T) {
        }{
                {"0", 'b', 0, "0"},
                {"-0", 'b', 0, "-0"},
-               {"1.0", 'b', 0, "4503599627370496p1"},
-               {"-1.0", 'b', 0, "-4503599627370496p1"},
+               {"1.0", 'b', 0, "4503599627370496p-52"},
+               {"-1.0", 'b', 0, "-4503599627370496p-52"},
+               {"4503599627370496", 'b', 0, "4503599627370496p+0"},
 
                {"0", 'p', 0, "0"},
                {"-0", 'p', 0, "-0"},
@@ -95,14 +94,21 @@ func TestFloatFormat(t *testing.T) {
                        t.Error(err)
                        continue
                }
+
                f := new(Float).SetFloat64(f64)
                got := f.Format(test.format, test.prec)
                if got != test.want {
-                       t.Errorf("%v: got %s", test, got)
+                       t.Errorf("%v: got %s; want %s", test, got, test.want)
                }
-               if test.format == 'b' || test.format == 'p' {
-                       continue // 'b', 'p' format not supported or different in strconv.Format
+
+               if test.format == 'b' && f64 == 0 {
+                       continue // 'b' format in strconv.Float requires knowledge of bias for 0.0
                }
+               if test.format == 'p' {
+                       continue // 'p' format not supported in strconv.Format
+               }
+
+               // verify that Float format matches strconv format
                want := strconv.FormatFloat(f64, test.format, test.prec, 64)
                if got != want {
                        t.Errorf("%v: got %s; want %s", test, got, want)