From: Russ Cox Date: Wed, 30 Jan 2019 05:49:33 +0000 (-0500) Subject: math/big: add %x float format X-Git-Tag: go1.13beta1~1390 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=675503c507194a48c01a39a0f25a6d0c9d772477;p=gostls13.git math/big: add %x float format big.Float already had %p for printing hex format, but that format normalizes differently from fmt's %x and ignores precision entirely. This CL adds %x to big.Float, matching fmt's behavior: the verb is spelled 'x' not 'p', the mantissa is normalized to [1, 2), and precision is respected. See golang.org/design/19308-number-literals for background. For #29008. Change-Id: I9c1b9612107094856797e5b0b584c556c1914895 Reviewed-on: https://go-review.googlesource.com/c/160249 Reviewed-by: Robert Griesemer --- diff --git a/src/math/big/floatconv_test.go b/src/math/big/floatconv_test.go index 154c818905..768943b902 100644 --- a/src/math/big/floatconv_test.go +++ b/src/math/big/floatconv_test.go @@ -268,7 +268,7 @@ func TestFloat64Text(t *testing.T) { {32, 'g', -1, "32"}, {32, 'g', 0, "3e+01"}, - // {100, 'x', -1, "%x"}, + {100, 'x', -1, "0x1.9p+06"}, // {math.NaN(), 'g', -1, "NaN"}, // Float doesn't support NaNs // {-math.NaN(), 'g', -1, "NaN"}, // Float doesn't support NaNs @@ -339,115 +339,166 @@ func actualPrec(x float64) uint { } func TestFloatText(t *testing.T) { + const defaultRound = ^RoundingMode(0) + for _, test := range []struct { x string + round RoundingMode prec uint format byte digits int want string }{ - {"0", 10, 'f', 0, "0"}, - {"-0", 10, 'f', 0, "-0"}, - {"1", 10, 'f', 0, "1"}, - {"-1", 10, 'f', 0, "-1"}, - - {"1.459", 100, 'e', 0, "1e+00"}, - {"2.459", 100, 'e', 1, "2.5e+00"}, - {"3.459", 100, 'e', 2, "3.46e+00"}, - {"4.459", 100, 'e', 3, "4.459e+00"}, - {"5.459", 100, 'e', 4, "5.4590e+00"}, - - {"1.459", 100, 'E', 0, "1E+00"}, - {"2.459", 100, 'E', 1, "2.5E+00"}, - {"3.459", 100, 'E', 2, "3.46E+00"}, - {"4.459", 100, 'E', 3, "4.459E+00"}, - {"5.459", 100, 'E', 4, "5.4590E+00"}, - - {"1.459", 100, 'f', 0, "1"}, - {"2.459", 100, 'f', 1, "2.5"}, - {"3.459", 100, 'f', 2, "3.46"}, - {"4.459", 100, 'f', 3, "4.459"}, - {"5.459", 100, 'f', 4, "5.4590"}, - - {"1.459", 100, 'g', 0, "1"}, - {"2.459", 100, 'g', 1, "2"}, - {"3.459", 100, 'g', 2, "3.5"}, - {"4.459", 100, 'g', 3, "4.46"}, - {"5.459", 100, 'g', 4, "5.459"}, - - {"1459", 53, 'g', 0, "1e+03"}, - {"2459", 53, 'g', 1, "2e+03"}, - {"3459", 53, 'g', 2, "3.5e+03"}, - {"4459", 53, 'g', 3, "4.46e+03"}, - {"5459", 53, 'g', 4, "5459"}, - - {"1459", 53, 'G', 0, "1E+03"}, - {"2459", 53, 'G', 1, "2E+03"}, - {"3459", 53, 'G', 2, "3.5E+03"}, - {"4459", 53, 'G', 3, "4.46E+03"}, - {"5459", 53, 'G', 4, "5459"}, - - {"3", 10, 'e', 40, "3.0000000000000000000000000000000000000000e+00"}, - {"3", 10, 'f', 40, "3.0000000000000000000000000000000000000000"}, - {"3", 10, 'g', 40, "3"}, - - {"3e40", 100, 'e', 40, "3.0000000000000000000000000000000000000000e+40"}, - {"3e40", 100, 'f', 4, "30000000000000000000000000000000000000000.0000"}, - {"3e40", 100, 'g', 40, "3e+40"}, + {"0", defaultRound, 10, 'f', 0, "0"}, + {"-0", defaultRound, 10, 'f', 0, "-0"}, + {"1", defaultRound, 10, 'f', 0, "1"}, + {"-1", defaultRound, 10, 'f', 0, "-1"}, + + {"1.459", defaultRound, 100, 'e', 0, "1e+00"}, + {"2.459", defaultRound, 100, 'e', 1, "2.5e+00"}, + {"3.459", defaultRound, 100, 'e', 2, "3.46e+00"}, + {"4.459", defaultRound, 100, 'e', 3, "4.459e+00"}, + {"5.459", defaultRound, 100, 'e', 4, "5.4590e+00"}, + + {"1.459", defaultRound, 100, 'E', 0, "1E+00"}, + {"2.459", defaultRound, 100, 'E', 1, "2.5E+00"}, + {"3.459", defaultRound, 100, 'E', 2, "3.46E+00"}, + {"4.459", defaultRound, 100, 'E', 3, "4.459E+00"}, + {"5.459", defaultRound, 100, 'E', 4, "5.4590E+00"}, + + {"1.459", defaultRound, 100, 'f', 0, "1"}, + {"2.459", defaultRound, 100, 'f', 1, "2.5"}, + {"3.459", defaultRound, 100, 'f', 2, "3.46"}, + {"4.459", defaultRound, 100, 'f', 3, "4.459"}, + {"5.459", defaultRound, 100, 'f', 4, "5.4590"}, + + {"1.459", defaultRound, 100, 'g', 0, "1"}, + {"2.459", defaultRound, 100, 'g', 1, "2"}, + {"3.459", defaultRound, 100, 'g', 2, "3.5"}, + {"4.459", defaultRound, 100, 'g', 3, "4.46"}, + {"5.459", defaultRound, 100, 'g', 4, "5.459"}, + + {"1459", defaultRound, 53, 'g', 0, "1e+03"}, + {"2459", defaultRound, 53, 'g', 1, "2e+03"}, + {"3459", defaultRound, 53, 'g', 2, "3.5e+03"}, + {"4459", defaultRound, 53, 'g', 3, "4.46e+03"}, + {"5459", defaultRound, 53, 'g', 4, "5459"}, + + {"1459", defaultRound, 53, 'G', 0, "1E+03"}, + {"2459", defaultRound, 53, 'G', 1, "2E+03"}, + {"3459", defaultRound, 53, 'G', 2, "3.5E+03"}, + {"4459", defaultRound, 53, 'G', 3, "4.46E+03"}, + {"5459", defaultRound, 53, 'G', 4, "5459"}, + + {"3", defaultRound, 10, 'e', 40, "3.0000000000000000000000000000000000000000e+00"}, + {"3", defaultRound, 10, 'f', 40, "3.0000000000000000000000000000000000000000"}, + {"3", defaultRound, 10, 'g', 40, "3"}, + + {"3e40", defaultRound, 100, 'e', 40, "3.0000000000000000000000000000000000000000e+40"}, + {"3e40", defaultRound, 100, 'f', 4, "30000000000000000000000000000000000000000.0000"}, + {"3e40", defaultRound, 100, 'g', 40, "3e+40"}, // make sure "stupid" exponents don't stall the machine - {"1e1000000", 64, 'p', 0, "0x.88b3a28a05eade3ap+3321929"}, - {"1e646456992", 64, 'p', 0, "0x.e883a0c5c8c7c42ap+2147483644"}, - {"1e646456993", 64, 'p', 0, "+Inf"}, - {"1e1000000000", 64, 'p', 0, "+Inf"}, - {"1e-1000000", 64, 'p', 0, "0x.efb4542cc8ca418ap-3321928"}, - {"1e-646456993", 64, 'p', 0, "0x.e17c8956983d9d59p-2147483647"}, - {"1e-646456994", 64, 'p', 0, "0"}, - {"1e-1000000000", 64, 'p', 0, "0"}, + {"1e1000000", defaultRound, 64, 'p', 0, "0x.88b3a28a05eade3ap+3321929"}, + {"1e646456992", defaultRound, 64, 'p', 0, "0x.e883a0c5c8c7c42ap+2147483644"}, + {"1e646456993", defaultRound, 64, 'p', 0, "+Inf"}, + {"1e1000000000", defaultRound, 64, 'p', 0, "+Inf"}, + {"1e-1000000", defaultRound, 64, 'p', 0, "0x.efb4542cc8ca418ap-3321928"}, + {"1e-646456993", defaultRound, 64, 'p', 0, "0x.e17c8956983d9d59p-2147483647"}, + {"1e-646456994", defaultRound, 64, 'p', 0, "0"}, + {"1e-1000000000", defaultRound, 64, 'p', 0, "0"}, // minimum and maximum values - {"1p2147483646", 64, 'p', 0, "0x.8p+2147483647"}, - {"0x.8p2147483647", 64, 'p', 0, "0x.8p+2147483647"}, - {"0x.8p-2147483647", 64, 'p', 0, "0x.8p-2147483647"}, - {"1p-2147483649", 64, 'p', 0, "0x.8p-2147483648"}, + {"1p2147483646", defaultRound, 64, 'p', 0, "0x.8p+2147483647"}, + {"0x.8p2147483647", defaultRound, 64, 'p', 0, "0x.8p+2147483647"}, + {"0x.8p-2147483647", defaultRound, 64, 'p', 0, "0x.8p-2147483647"}, + {"1p-2147483649", defaultRound, 64, 'p', 0, "0x.8p-2147483648"}, // TODO(gri) need tests for actual large Floats - {"0", 53, 'b', 0, "0"}, - {"-0", 53, 'b', 0, "-0"}, - {"1.0", 53, 'b', 0, "4503599627370496p-52"}, - {"-1.0", 53, 'b', 0, "-4503599627370496p-52"}, - {"4503599627370496", 53, 'b', 0, "4503599627370496p+0"}, + {"0", defaultRound, 53, 'b', 0, "0"}, + {"-0", defaultRound, 53, 'b', 0, "-0"}, + {"1.0", defaultRound, 53, 'b', 0, "4503599627370496p-52"}, + {"-1.0", defaultRound, 53, 'b', 0, "-4503599627370496p-52"}, + {"4503599627370496", defaultRound, 53, 'b', 0, "4503599627370496p+0"}, // issue 9939 - {"3", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, - {"03", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, - {"3.", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, - {"3.0", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, - {"3.00", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, - {"3.000", 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, - - {"3", 350, 'p', 0, "0x.cp+2"}, - {"03", 350, 'p', 0, "0x.cp+2"}, - {"3.", 350, 'p', 0, "0x.cp+2"}, - {"3.0", 350, 'p', 0, "0x.cp+2"}, - {"3.00", 350, 'p', 0, "0x.cp+2"}, - {"3.000", 350, 'p', 0, "0x.cp+2"}, - - {"0", 64, 'p', 0, "0"}, - {"-0", 64, 'p', 0, "-0"}, - {"1024.0", 64, 'p', 0, "0x.8p+11"}, - {"-1024.0", 64, 'p', 0, "-0x.8p+11"}, - - // unsupported format - //{"3.14", 64, 'x', 0, "%x"}, - //{"-3.14", 64, 'x', 0, "%x"}, + {"3", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, + {"03", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, + {"3.", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, + {"3.0", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, + {"3.00", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, + {"3.000", defaultRound, 350, 'b', 0, "1720123961992553633708115671476565205597423741876210842803191629540192157066363606052513914832594264915968p-348"}, + + {"3", defaultRound, 350, 'p', 0, "0x.cp+2"}, + {"03", defaultRound, 350, 'p', 0, "0x.cp+2"}, + {"3.", defaultRound, 350, 'p', 0, "0x.cp+2"}, + {"3.0", defaultRound, 350, 'p', 0, "0x.cp+2"}, + {"3.00", defaultRound, 350, 'p', 0, "0x.cp+2"}, + {"3.000", defaultRound, 350, 'p', 0, "0x.cp+2"}, + + {"0", defaultRound, 64, 'p', 0, "0"}, + {"-0", defaultRound, 64, 'p', 0, "-0"}, + {"1024.0", defaultRound, 64, 'p', 0, "0x.8p+11"}, + {"-1024.0", defaultRound, 64, 'p', 0, "-0x.8p+11"}, + + {"0", defaultRound, 64, 'x', -1, "0x0p+00"}, + {"0", defaultRound, 64, 'x', 0, "0x0p+00"}, + {"0", defaultRound, 64, 'x', 1, "0x0.0p+00"}, + {"0", defaultRound, 64, 'x', 5, "0x0.00000p+00"}, + {"3.25", defaultRound, 64, 'x', 0, "0x1p+02"}, + {"-3.25", defaultRound, 64, 'x', 0, "-0x1p+02"}, + {"3.25", defaultRound, 64, 'x', 1, "0x1.ap+01"}, + {"-3.25", defaultRound, 64, 'x', 1, "-0x1.ap+01"}, + {"3.25", defaultRound, 64, 'x', -1, "0x1.ap+01"}, + {"-3.25", defaultRound, 64, 'x', -1, "-0x1.ap+01"}, + {"1024.0", defaultRound, 64, 'x', 0, "0x1p+10"}, + {"-1024.0", defaultRound, 64, 'x', 0, "-0x1p+10"}, + {"1024.0", defaultRound, 64, 'x', 5, "0x1.00000p+10"}, + {"8191.0", defaultRound, 53, 'x', -1, "0x1.fffp+12"}, + {"8191.5", defaultRound, 53, 'x', -1, "0x1.fff8p+12"}, + {"8191.53125", defaultRound, 53, 'x', -1, "0x1.fff88p+12"}, + {"8191.53125", defaultRound, 53, 'x', 4, "0x1.fff8p+12"}, + {"8191.53125", defaultRound, 53, 'x', 3, "0x1.000p+13"}, + {"8191.53125", defaultRound, 53, 'x', 0, "0x1p+13"}, + {"8191.533203125", defaultRound, 53, 'x', -1, "0x1.fff888p+12"}, + {"8191.533203125", defaultRound, 53, 'x', 5, "0x1.fff88p+12"}, + {"8191.533203125", defaultRound, 53, 'x', 4, "0x1.fff9p+12"}, + + {"8191.53125", defaultRound, 53, 'x', -1, "0x1.fff88p+12"}, + {"8191.53125", ToNearestEven, 53, 'x', 5, "0x1.fff88p+12"}, + {"8191.53125", ToNearestAway, 53, 'x', 5, "0x1.fff88p+12"}, + {"8191.53125", ToZero, 53, 'x', 5, "0x1.fff88p+12"}, + {"8191.53125", AwayFromZero, 53, 'x', 5, "0x1.fff88p+12"}, + {"8191.53125", ToNegativeInf, 53, 'x', 5, "0x1.fff88p+12"}, + {"8191.53125", ToPositiveInf, 53, 'x', 5, "0x1.fff88p+12"}, + + {"8191.53125", defaultRound, 53, 'x', 4, "0x1.fff8p+12"}, + {"8191.53125", defaultRound, 53, 'x', 3, "0x1.000p+13"}, + {"8191.53125", defaultRound, 53, 'x', 0, "0x1p+13"}, + {"8191.533203125", defaultRound, 53, 'x', -1, "0x1.fff888p+12"}, + {"8191.533203125", defaultRound, 53, 'x', 6, "0x1.fff888p+12"}, + {"8191.533203125", defaultRound, 53, 'x', 5, "0x1.fff88p+12"}, + {"8191.533203125", defaultRound, 53, 'x', 4, "0x1.fff9p+12"}, + + {"8191.53125", ToNearestEven, 53, 'x', 4, "0x1.fff8p+12"}, + {"8191.53125", ToNearestAway, 53, 'x', 4, "0x1.fff9p+12"}, + {"8191.53125", ToZero, 53, 'x', 4, "0x1.fff8p+12"}, + {"8191.53125", ToZero, 53, 'x', 2, "0x1.ffp+12"}, + {"8191.53125", AwayFromZero, 53, 'x', 4, "0x1.fff9p+12"}, + {"8191.53125", ToNegativeInf, 53, 'x', 4, "0x1.fff8p+12"}, + {"-8191.53125", ToNegativeInf, 53, 'x', 4, "-0x1.fff9p+12"}, + {"8191.53125", ToPositiveInf, 53, 'x', 4, "0x1.fff9p+12"}, + {"-8191.53125", ToPositiveInf, 53, 'x', 4, "-0x1.fff8p+12"}, } { f, _, err := ParseFloat(test.x, 0, test.prec, ToNearestEven) if err != nil { t.Errorf("%v: %s", test, err) continue } + if test.round != defaultRound { + f.SetMode(test.round) + } got := f.Text(test.format, test.digits) if got != test.want { @@ -458,7 +509,7 @@ func TestFloatText(t *testing.T) { // ('p' format is not supported by strconv.FormatFloat, // and its output for 0.0 prints a biased exponent value // as in 0p-1074 which makes no sense to emulate here) - if test.prec == 53 && test.format != 'p' && f.Sign() != 0 { + if test.prec == 53 && test.format != 'p' && f.Sign() != 0 && (test.round == ToNearestEven || test.round == defaultRound) { f64, acc := f.Float64() if acc != Exact { t.Errorf("%v: expected exact conversion to float64", test) diff --git a/src/math/big/ftoa.go b/src/math/big/ftoa.go index d2a85886c7..6cae63ed09 100644 --- a/src/math/big/ftoa.go +++ b/src/math/big/ftoa.go @@ -22,24 +22,28 @@ import ( // 'f' -ddddd.dddd, no exponent // 'g' like 'e' for large exponents, like 'f' otherwise // 'G' like 'E' for large exponents, like 'f' otherwise -// 'b' -ddddddp±dd, binary exponent -// 'p' -0x.dddp±dd, binary exponent, hexadecimal mantissa +// 'x' -0xd.dddddp±dd, hexadecimal mantissa, decimal power of two exponent +// 'p' -0x.dddp±dd, hexadecimal mantissa, decimal power of two exponent (non-standard) +// 'b' -ddddddp±dd, decimal mantissa, decimal power of two exponent (non-standard) // -// For the binary exponent formats, the mantissa is printed in normalized form: +// For the power-of-two exponent formats, the mantissa is printed in normalized form: // -// 'b' decimal integer mantissa using x.Prec() bits, or -0 -// 'p' hexadecimal fraction with 0.5 <= 0.mantissa < 1.0, or -0 +// 'x' hexadecimal mantissa in [1, 2), or 0 +// 'p' hexadecimal mantissa in [½, 1), or 0 +// 'b' decimal integer mantissa using x.Prec() bits, or 0 +// +// Note that the 'x' form is the one used by most other languages and libraries. // // If format is a different character, Text returns a "%" followed by the // unrecognized format character. // // The precision prec controls the number of digits (excluding the exponent) -// printed by the 'e', 'E', 'f', 'g', and 'G' formats. For 'e', 'E', and 'f' -// it is the number of digits after the decimal point. For 'g' and 'G' it is -// the total number of digits. A negative precision selects the smallest -// number of decimal digits necessary to identify the value x uniquely using -// x.Prec() mantissa bits. -// The prec value is ignored for the 'b' or 'p' format. +// printed by the 'e', 'E', 'f', 'g', 'G', and 'x' formats. +// For 'e', 'E', 'f', and 'x', it is the number of digits after the decimal point. +// For 'g' and 'G' it is the total number of digits. A negative precision selects +// the smallest number of decimal digits necessary to identify the value x uniquely +// using x.Prec() mantissa bits. +// The prec value is ignored for the 'b' and 'p' formats. func (x *Float) Text(format byte, prec int) string { cap := 10 // TODO(gri) determine a good/better value here if prec > 0 { @@ -76,6 +80,8 @@ func (x *Float) Append(buf []byte, fmt byte, prec int) []byte { return x.fmtB(buf) case 'p': return x.fmtP(buf) + case 'x': + return x.fmtX(buf, prec) } // Algorithm: @@ -308,6 +314,7 @@ func fmtF(buf []byte, prec int, d decimal) []byte { // The mantissa is normalized such that is uses x.Prec() bits in binary // representation. // The sign of x is ignored, and x must not be an Inf. +// (The caller handles Inf before invoking fmtB.) func (x *Float) fmtB(buf []byte) []byte { if x.form == zero { return append(buf, '0') @@ -336,11 +343,80 @@ func (x *Float) fmtB(buf []byte) []byte { return strconv.AppendInt(buf, e, 10) } +// fmtX appends the string of x in the format "0x1." mantissa "p" exponent +// with a hexadecimal mantissa and a binary exponent, or "0x0p0" if x is zero, +// and returns the extended buffer. +// A non-zero mantissa is normalized such that 1.0 <= mantissa < 2.0. +// The sign of x is ignored, and x must not be an Inf. +// (The caller handles Inf before invoking fmtX.) +func (x *Float) fmtX(buf []byte, prec int) []byte { + if x.form == zero { + buf = append(buf, "0x0"...) + if prec > 0 { + buf = append(buf, '.') + for i := 0; i < prec; i++ { + buf = append(buf, '0') + } + } + buf = append(buf, "p+00"...) + return buf + } + + if debugFloat && x.form != finite { + panic("non-finite float") + } + + // round mantissa to n bits + var n uint + if prec < 0 { + n = 1 + (x.MinPrec()-1+3)/4*4 // round MinPrec up to 1 mod 4 + } else { + n = 1 + 4*uint(prec) + } + // n%4 == 1 + x = new(Float).SetPrec(n).SetMode(x.mode).Set(x) + + // adjust mantissa to use exactly n bits + m := x.mant + switch w := uint(len(x.mant)) * _W; { + case w < n: + m = nat(nil).shl(m, n-w) + case w > n: + m = nat(nil).shr(m, w-n) + } + exp := x.exp - 1 + + hm := m.utoa(16) + if debugFloat && hm[0] != '1' { + panic("incorrect mantissa: " + string(hm)) + } + buf = append(buf, "0x1"...) + if len(hm) > 1 { + buf = append(buf, '.') + buf = append(buf, hm[1:]...) + } + + buf = append(buf, 'p') + exp64 := int64(exp) + if exp64 >= 0 { + buf = append(buf, '+') + } else { + exp64 = -exp64 + buf = append(buf, '-') + } + // Force at least two exponent digits, to match fmt. + if exp64 < 10 { + buf = append(buf, '0') + } + return strconv.AppendInt(buf, exp64, 10) +} + // fmtP 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, // and returns the extended buffer. // The mantissa is normalized such that 0.5 <= 0.mantissa < 1.0. // The sign of x is ignored, and x must not be an Inf. +// (The caller handles Inf before invoking fmtP.) func (x *Float) fmtP(buf []byte) []byte { if x.form == zero { return append(buf, '0') @@ -380,7 +456,7 @@ var _ fmt.Formatter = &floatZero // *Float must implement fmt.Formatter // Format implements fmt.Formatter. It accepts all the regular // formats for floating-point numbers ('b', 'e', 'E', 'f', 'F', -// 'g', 'G') as well as 'p' and 'v'. See (*Float).Text for the +// 'g', 'G', 'x') as well as 'p' and 'v'. See (*Float).Text for the // interpretation of 'p'. The 'v' format is handled like 'g'. // Format also supports specification of the minimum precision // in digits, the output field width, as well as the format flags @@ -394,7 +470,7 @@ func (x *Float) Format(s fmt.State, format rune) { } switch format { - case 'e', 'E', 'f', 'b', 'p': + case 'e', 'E', 'f', 'b', 'p', 'x': // nothing to do case 'F': // (*Float).Text doesn't support 'F'; handle like 'f'