mirror of
https://github.com/golang/go
synced 2024-11-18 14:54:40 -07:00
math/big: build Float.Format on top of Float.Append
Change-Id: I444eec24467f827caa5c88a1c5ae5bce92508b98 Reviewed-on: https://go-review.googlesource.com/3750 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
2e5b065ac2
commit
4c91c0d07b
@ -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))
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user