mirror of
https://github.com/golang/go
synced 2024-11-05 17:36:15 -07:00
math/big: fix %b format so it matches strconf %b format for non-zero values
(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>
This commit is contained in:
parent
bbd6771621
commit
b8fcae02b0
@ -205,12 +205,6 @@ func (x *Float) String() string {
|
|||||||
return x.Format('p', 0)
|
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
|
// 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,
|
// with a decimal mantissa and a binary exponent, or ["-"] "0" if x is zero,
|
||||||
// and returns the extended buffer.
|
// and returns the extended buffer.
|
||||||
@ -233,7 +227,11 @@ func (x *Float) bstring(buf []byte) []byte {
|
|||||||
}
|
}
|
||||||
buf = append(buf, m.decimalString()...)
|
buf = append(buf, m.decimalString()...)
|
||||||
buf = append(buf, 'p')
|
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
|
// pstring appends the string of x in the format ["-"] "0x." mantissa "p" exponent
|
||||||
|
@ -9,55 +9,53 @@ import (
|
|||||||
"testing"
|
"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},
|
|
||||||
|
|
||||||
{"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)},
|
|
||||||
|
|
||||||
{"-687436.79457e-245", -687436.79457e-245},
|
|
||||||
{"-687436.79457E245", -687436.79457e245},
|
|
||||||
{"1024.p-12", 0.25},
|
|
||||||
{"-1.p10", -1024},
|
|
||||||
{"0.25p2", 1},
|
|
||||||
|
|
||||||
{".0000000000000000000000000000000000000001", 1e-40},
|
|
||||||
{"+10000000000000000000000000000000000000000e-0", 1e40},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestFloatSetFloat64String(t *testing.T) {
|
func TestFloatSetFloat64String(t *testing.T) {
|
||||||
for _, test := range floatSetFloat64StringTests {
|
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},
|
||||||
|
|
||||||
|
{"0e100", 0},
|
||||||
|
{"-0e+100", 0},
|
||||||
|
{"+0e-100", 0},
|
||||||
|
{"0E100", 0},
|
||||||
|
{"-0E+100", 0},
|
||||||
|
{"+0E-100", 0},
|
||||||
|
{"0p100", 0},
|
||||||
|
{"-0p+100", 0},
|
||||||
|
{"+0p-100", 0},
|
||||||
|
|
||||||
|
{"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)},
|
||||||
|
|
||||||
|
{"-687436.79457e-245", -687436.79457e-245},
|
||||||
|
{"-687436.79457E245", -687436.79457e245},
|
||||||
|
{"1024.p-12", 0.25},
|
||||||
|
{"-1.p10", -1024},
|
||||||
|
{"0.25p2", 1},
|
||||||
|
|
||||||
|
{".0000000000000000000000000000000000000001", 1e-40},
|
||||||
|
{"+10000000000000000000000000000000000000000e-0", 1e40},
|
||||||
|
} {
|
||||||
var x Float
|
var x Float
|
||||||
x.prec = 53 // TODO(gri) find better solution
|
x.prec = 53 // TODO(gri) find better solution
|
||||||
_, ok := x.SetString(test.s)
|
_, ok := x.SetString(test.s)
|
||||||
@ -82,8 +80,9 @@ func TestFloatFormat(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"0", 'b', 0, "0"},
|
{"0", 'b', 0, "0"},
|
||||||
{"-0", 'b', 0, "-0"},
|
{"-0", 'b', 0, "-0"},
|
||||||
{"1.0", 'b', 0, "4503599627370496p1"},
|
{"1.0", 'b', 0, "4503599627370496p-52"},
|
||||||
{"-1.0", 'b', 0, "-4503599627370496p1"},
|
{"-1.0", 'b', 0, "-4503599627370496p-52"},
|
||||||
|
{"4503599627370496", 'b', 0, "4503599627370496p+0"},
|
||||||
|
|
||||||
{"0", 'p', 0, "0"},
|
{"0", 'p', 0, "0"},
|
||||||
{"-0", 'p', 0, "-0"},
|
{"-0", 'p', 0, "-0"},
|
||||||
@ -95,14 +94,21 @@ func TestFloatFormat(t *testing.T) {
|
|||||||
t.Error(err)
|
t.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
f := new(Float).SetFloat64(f64)
|
f := new(Float).SetFloat64(f64)
|
||||||
got := f.Format(test.format, test.prec)
|
got := f.Format(test.format, test.prec)
|
||||||
if got != test.want {
|
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)
|
want := strconv.FormatFloat(f64, test.format, test.prec, 64)
|
||||||
if got != want {
|
if got != want {
|
||||||
t.Errorf("%v: got %s; want %s", test, got, want)
|
t.Errorf("%v: got %s; want %s", test, got, want)
|
||||||
|
Loading…
Reference in New Issue
Block a user