From 1329aa51b605cb54ba9aae3a82a0a87b881fb7b3 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 13 Nov 2017 09:09:58 -0800 Subject: Updating server dependancies. (#7816) --- .../golang.org/x/text/internal/number/decimal.go | 46 ++++++++++++++-------- .../x/text/internal/number/decimal_test.go | 39 ++++++++++++------ 2 files changed, 57 insertions(+), 28 deletions(-) (limited to 'vendor/golang.org/x/text/internal/number') diff --git a/vendor/golang.org/x/text/internal/number/decimal.go b/vendor/golang.org/x/text/internal/number/decimal.go index 62074e7d7..9b4035ec4 100644 --- a/vendor/golang.org/x/text/internal/number/decimal.go +++ b/vendor/golang.org/x/text/internal/number/decimal.go @@ -406,23 +406,35 @@ func (d *Decimal) ConvertFloat(r RoundingContext, x float64, size int) { // By default we get the exact decimal representation. verb := byte('g') prec := -1 - // Determine rounding, if possible. As the strconv API does not return the - // rounding accuracy (exact/rounded up|down), we can only round using - // ToNearestEven. - // Something like this would work: - // AppendDigits(dst []byte, x float64, base, size, prec int) (digits []byte, exp, accuracy int) - // - // TODO: At this point strconv's rounding is imprecise to the point that it - // is not useable for this purpose. - // See https://github.com/golang/go/issues/21714 - // if r.Mode == ToNearestEven { - // if n := r.RoundSignificantDigits(); n >= 0 { - // prec = n - // } else if n = r.RoundFractionDigits(); n >= 0 { - // prec = n - // verb = 'f' - // } - // } + // As the strconv API does not return the rounding accuracy, we can only + // round using ToNearestEven. + if r.Mode == ToNearestEven { + if n := r.RoundSignificantDigits(); n >= 0 { + prec = n + } else if n = r.RoundFractionDigits(); n >= 0 { + prec = n + verb = 'f' + } + } else { + // TODO: At this point strconv's rounding is imprecise to the point that + // it is not useable for this purpose. + // See https://github.com/golang/go/issues/21714 + // If rounding is requested, we ask for a large number of digits and + // round from there to simulate rounding only once. + // Ideally we would have strconv export an AppendDigits that would take + // a rounding mode and/or return an accuracy. Something like this would + // work: + // AppendDigits(dst []byte, x float64, base, size, prec int) (digits []byte, exp, accuracy int) + hasPrec := r.RoundSignificantDigits() >= 0 + hasScale := r.RoundFractionDigits() >= 0 + if hasPrec || hasScale { + // prec is the number of mantissa bits plus some extra for safety. + // We need at least the number of mantissa bits as decimals to + // accurately represent the floating point without rounding, as each + // bit requires one more decimal to represent: 0.5, 0.25, 0.125, ... + prec = 60 + } + } b := strconv.AppendFloat(d.Digits[:0], abs, verb, prec, size) i := 0 diff --git a/vendor/golang.org/x/text/internal/number/decimal_test.go b/vendor/golang.org/x/text/internal/number/decimal_test.go index 04aa8b2c8..97c7e25b6 100644 --- a/vendor/golang.org/x/text/internal/number/decimal_test.go +++ b/vendor/golang.org/x/text/internal/number/decimal_test.go @@ -256,12 +256,10 @@ func TestConvert(t *testing.T) { rc RoundingContext out string }{ - // TODO: uncommented tests can be restored when convert does its own - // rounding. - // {-0.001, scale2, "-0.00"}, // not normalized - // {0.1234, prec3, "0.123"}, - // {1234.0, prec3, "1230"}, - // {1.2345e10, prec3, "12300000000"}, + {-0.001, scale2, "-0.00"}, + {0.1234, prec3, "0.123"}, + {1234.0, prec3, "1230"}, + {1.2345e10, prec3, "12300000000"}, {int8(-34), scale2, "-34"}, {int16(-234), scale2, "-234"}, @@ -273,18 +271,37 @@ func TestConvert(t *testing.T) { {uint32(234), scale2, "234"}, {uint64(234), scale2, "234"}, {uint(234), scale2, "234"}, - {-1e9, scale2, "-1000000000"}, - {0.234, scale2away, "0.234"}, // rounding postponed as not ToNearestEven + {-1e9, scale2, "-1000000000.00"}, + // The following two causes this result to have a lot of digits: + // 1) 0.234 cannot be accurately represented as a float64, and + // 2) as strconv does not support the rounding AwayFromZero, Convert + // leaves the rounding to caller. + {0.234, scale2away, + "0.2340000000000000135447209004269097931683063507080078125"}, + {0.0249, inc0_05, "0.00"}, + {0.025, inc0_05, "0.00"}, + {0.0251, inc0_05, "0.05"}, {0.03, inc0_05, "0.05"}, - {0.025, inc0_05, "0"}, - {0.075, inc0_05, "0.1"}, + {0.049, inc0_05, "0.05"}, + {0.05, inc0_05, "0.05"}, + {0.051, inc0_05, "0.05"}, + {0.0749, inc0_05, "0.05"}, + {0.075, inc0_05, "0.10"}, + {0.0751, inc0_05, "0.10"}, + {324, inc50, "300"}, {325, inc50, "300"}, + {326, inc50, "350"}, + {349, inc50, "350"}, + {350, inc50, "350"}, + {351, inc50, "350"}, + {374, inc50, "350"}, {375, inc50, "400"}, + {376, inc50, "400"}, // Here the scale is 2, but the digits get shifted left. As we use // AppendFloat to do the rounding an exta 0 gets added. - {0.123, roundShift, "0.123"}, + {0.123, roundShift, "0.1230"}, {converter(3), scale2, "100"}, -- cgit v1.2.3-1-g7c22