go/src/internal/strconv/ftoa_test.go

353 lines
10 KiB
Go
Raw Normal View History

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package strconv_test
import (
. "internal/strconv"
"math"
"math/rand"
"testing"
)
type ftoaTest struct {
f float64
fmt byte
prec int
s string
}
func fdiv(a, b float64) float64 { return a / b }
const (
below1e23 = 99999999999999974834176
above1e23 = 100000000000000008388608
)
var ftoatests = []ftoaTest{
{1, 'e', 5, "1.00000e+00"},
{1, 'f', 5, "1.00000"},
{1, 'g', 5, "1"},
{1, 'g', -1, "1"},
{1, 'x', -1, "0x1p+00"},
{1, 'x', 5, "0x1.00000p+00"},
{20, 'g', -1, "20"},
{20, 'x', -1, "0x1.4p+04"},
{1234567.8, 'g', -1, "1.2345678e+06"},
{1234567.8, 'x', -1, "0x1.2d687cccccccdp+20"},
{200000, 'g', -1, "200000"},
{200000, 'x', -1, "0x1.86ap+17"},
{200000, 'X', -1, "0X1.86AP+17"},
{2000000, 'g', -1, "2e+06"},
strconv: Implement Ryū algorithm for ftoa shortest mode This patch implements the algorithm from Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369) for formatting floating-point numbers with a fixed number of decimal digits. It is not a direct translation of the reference C implementation but still follows the original paper. In particular, it uses full 128-bit powers of 10, which allows for more precision in the other modes (fixed ftoa, atof). name old time/op new time/op delta AppendFloat/Decimal-4 49.6ns ± 3% 59.3ns ± 0% +19.59% (p=0.008 n=5+5) AppendFloat/Float-4 122ns ± 1% 91ns ± 1% -25.92% (p=0.008 n=5+5) AppendFloat/Exp-4 89.3ns ± 1% 100.0ns ± 1% +11.98% (p=0.008 n=5+5) AppendFloat/NegExp-4 88.3ns ± 2% 97.1ns ± 1% +9.87% (p=0.008 n=5+5) AppendFloat/LongExp-4 143ns ± 2% 103ns ± 0% -28.17% (p=0.016 n=5+4) AppendFloat/Big-4 144ns ± 1% 110ns ± 1% -23.26% (p=0.008 n=5+5) AppendFloat/BinaryExp-4 46.2ns ± 2% 46.0ns ± 1% ~ (p=0.603 n=5+5) AppendFloat/32Integer-4 49.1ns ± 1% 58.7ns ± 1% +19.57% (p=0.008 n=5+5) AppendFloat/32ExactFraction-4 95.6ns ± 1% 88.6ns ± 1% -7.30% (p=0.008 n=5+5) AppendFloat/32Point-4 122ns ± 1% 87ns ± 1% -28.63% (p=0.008 n=5+5) AppendFloat/32Exp-4 88.6ns ± 2% 95.0ns ± 1% +7.29% (p=0.008 n=5+5) AppendFloat/32NegExp-4 87.2ns ± 1% 91.3ns ± 1% +4.63% (p=0.008 n=5+5) AppendFloat/32Shortest-4 107ns ± 1% 82ns ± 0% -24.08% (p=0.008 n=5+5) AppendFloat/Slowpath64-4 1.00µs ± 1% 0.10µs ± 0% -89.92% (p=0.016 n=5+4) AppendFloat/SlowpathDenormal64-4 34.1µs ± 3% 0.1µs ± 1% -99.72% (p=0.008 n=5+5) Fixes #15672 Change-Id: Ib90dfa245f62490a6666671896013cf3f9a1fb22 Reviewed-on: https://go-review.googlesource.com/c/go/+/170080 Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Nigel Tao <nigeltao@golang.org> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Nigel Tao <nigeltao@golang.org>
2019-03-27 06:55:52 +01:00
{1e10, 'g', -1, "1e+10"},
// g conversion and zero suppression
{400, 'g', 2, "4e+02"},
{40, 'g', 2, "40"},
{4, 'g', 2, "4"},
{.4, 'g', 2, "0.4"},
{.04, 'g', 2, "0.04"},
{.004, 'g', 2, "0.004"},
{.0004, 'g', 2, "0.0004"},
{.00004, 'g', 2, "4e-05"},
{.000004, 'g', 2, "4e-06"},
{0, 'e', 5, "0.00000e+00"},
{0, 'f', 5, "0.00000"},
{0, 'g', 5, "0"},
{0, 'g', -1, "0"},
{0, 'x', 5, "0x0.00000p+00"},
{-1, 'e', 5, "-1.00000e+00"},
{-1, 'f', 5, "-1.00000"},
{-1, 'g', 5, "-1"},
{-1, 'g', -1, "-1"},
{12, 'e', 5, "1.20000e+01"},
{12, 'f', 5, "12.00000"},
{12, 'g', 5, "12"},
{12, 'g', -1, "12"},
{123456700, 'e', 5, "1.23457e+08"},
{123456700, 'f', 5, "123456700.00000"},
{123456700, 'g', 5, "1.2346e+08"},
{123456700, 'g', -1, "1.234567e+08"},
{1.2345e6, 'e', 5, "1.23450e+06"},
{1.2345e6, 'f', 5, "1234500.00000"},
{1.2345e6, 'g', 5, "1.2345e+06"},
strconv: implement Ryū-like algorithm for fixed precision ftoa This patch implements a simplified version of Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369) for formatting floating-point numbers with a fixed number of decimal digits. It uses the same principles but does not need to handle the complex task of finding a shortest representation. This allows to handle a few more cases than Grisu3, notably formatting with up to 18 significant digits. name old time/op new time/op delta AppendFloat/32Fixed8Hard-4 72.0ns ± 2% 56.0ns ± 2% -22.28% (p=0.000 n=10+10) AppendFloat/32Fixed9Hard-4 74.8ns ± 0% 64.2ns ± 2% -14.16% (p=0.000 n=8+10) AppendFloat/64Fixed1-4 60.4ns ± 1% 54.2ns ± 1% -10.31% (p=0.000 n=10+9) AppendFloat/64Fixed2-4 66.3ns ± 1% 53.3ns ± 1% -19.54% (p=0.000 n=10+9) AppendFloat/64Fixed3-4 61.0ns ± 1% 55.0ns ± 2% -9.80% (p=0.000 n=9+10) AppendFloat/64Fixed4-4 66.9ns ± 0% 52.0ns ± 2% -22.20% (p=0.000 n=8+10) AppendFloat/64Fixed12-4 95.5ns ± 1% 76.2ns ± 3% -20.19% (p=0.000 n=10+9) AppendFloat/64Fixed16-4 1.62µs ± 0% 0.07µs ± 2% -95.69% (p=0.000 n=10+10) AppendFloat/64Fixed12Hard-4 1.27µs ± 1% 0.07µs ± 1% -94.83% (p=0.000 n=9+9) AppendFloat/64Fixed17Hard-4 3.68µs ± 1% 0.08µs ± 2% -97.86% (p=0.000 n=10+9) AppendFloat/64Fixed18Hard-4 3.67µs ± 0% 3.72µs ± 1% +1.44% (p=0.000 n=9+10) Updates #15672 Change-Id: I160963e141dd48287ad8cf57bcc3c686277788e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/170079 Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Nigel Tao <nigeltao@golang.org> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org>
2019-03-24 23:21:38 +01:00
// Round to even
{1.2345e6, 'e', 3, "1.234e+06"},
{1.2355e6, 'e', 3, "1.236e+06"},
{1.2345, 'f', 3, "1.234"},
{1.2355, 'f', 3, "1.236"},
{1234567890123456.5, 'e', 15, "1.234567890123456e+15"},
{1234567890123457.5, 'e', 15, "1.234567890123458e+15"},
strconv: Implement Ryū algorithm for ftoa shortest mode This patch implements the algorithm from Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369) for formatting floating-point numbers with a fixed number of decimal digits. It is not a direct translation of the reference C implementation but still follows the original paper. In particular, it uses full 128-bit powers of 10, which allows for more precision in the other modes (fixed ftoa, atof). name old time/op new time/op delta AppendFloat/Decimal-4 49.6ns ± 3% 59.3ns ± 0% +19.59% (p=0.008 n=5+5) AppendFloat/Float-4 122ns ± 1% 91ns ± 1% -25.92% (p=0.008 n=5+5) AppendFloat/Exp-4 89.3ns ± 1% 100.0ns ± 1% +11.98% (p=0.008 n=5+5) AppendFloat/NegExp-4 88.3ns ± 2% 97.1ns ± 1% +9.87% (p=0.008 n=5+5) AppendFloat/LongExp-4 143ns ± 2% 103ns ± 0% -28.17% (p=0.016 n=5+4) AppendFloat/Big-4 144ns ± 1% 110ns ± 1% -23.26% (p=0.008 n=5+5) AppendFloat/BinaryExp-4 46.2ns ± 2% 46.0ns ± 1% ~ (p=0.603 n=5+5) AppendFloat/32Integer-4 49.1ns ± 1% 58.7ns ± 1% +19.57% (p=0.008 n=5+5) AppendFloat/32ExactFraction-4 95.6ns ± 1% 88.6ns ± 1% -7.30% (p=0.008 n=5+5) AppendFloat/32Point-4 122ns ± 1% 87ns ± 1% -28.63% (p=0.008 n=5+5) AppendFloat/32Exp-4 88.6ns ± 2% 95.0ns ± 1% +7.29% (p=0.008 n=5+5) AppendFloat/32NegExp-4 87.2ns ± 1% 91.3ns ± 1% +4.63% (p=0.008 n=5+5) AppendFloat/32Shortest-4 107ns ± 1% 82ns ± 0% -24.08% (p=0.008 n=5+5) AppendFloat/Slowpath64-4 1.00µs ± 1% 0.10µs ± 0% -89.92% (p=0.016 n=5+4) AppendFloat/SlowpathDenormal64-4 34.1µs ± 3% 0.1µs ± 1% -99.72% (p=0.008 n=5+5) Fixes #15672 Change-Id: Ib90dfa245f62490a6666671896013cf3f9a1fb22 Reviewed-on: https://go-review.googlesource.com/c/go/+/170080 Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Nigel Tao <nigeltao@golang.org> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Nigel Tao <nigeltao@golang.org>
2019-03-27 06:55:52 +01:00
{108678236358137.625, 'g', -1, "1.0867823635813762e+14"},
strconv: implement Ryū-like algorithm for fixed precision ftoa This patch implements a simplified version of Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369) for formatting floating-point numbers with a fixed number of decimal digits. It uses the same principles but does not need to handle the complex task of finding a shortest representation. This allows to handle a few more cases than Grisu3, notably formatting with up to 18 significant digits. name old time/op new time/op delta AppendFloat/32Fixed8Hard-4 72.0ns ± 2% 56.0ns ± 2% -22.28% (p=0.000 n=10+10) AppendFloat/32Fixed9Hard-4 74.8ns ± 0% 64.2ns ± 2% -14.16% (p=0.000 n=8+10) AppendFloat/64Fixed1-4 60.4ns ± 1% 54.2ns ± 1% -10.31% (p=0.000 n=10+9) AppendFloat/64Fixed2-4 66.3ns ± 1% 53.3ns ± 1% -19.54% (p=0.000 n=10+9) AppendFloat/64Fixed3-4 61.0ns ± 1% 55.0ns ± 2% -9.80% (p=0.000 n=9+10) AppendFloat/64Fixed4-4 66.9ns ± 0% 52.0ns ± 2% -22.20% (p=0.000 n=8+10) AppendFloat/64Fixed12-4 95.5ns ± 1% 76.2ns ± 3% -20.19% (p=0.000 n=10+9) AppendFloat/64Fixed16-4 1.62µs ± 0% 0.07µs ± 2% -95.69% (p=0.000 n=10+10) AppendFloat/64Fixed12Hard-4 1.27µs ± 1% 0.07µs ± 1% -94.83% (p=0.000 n=9+9) AppendFloat/64Fixed17Hard-4 3.68µs ± 1% 0.08µs ± 2% -97.86% (p=0.000 n=10+9) AppendFloat/64Fixed18Hard-4 3.67µs ± 0% 3.72µs ± 1% +1.44% (p=0.000 n=9+10) Updates #15672 Change-Id: I160963e141dd48287ad8cf57bcc3c686277788e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/170079 Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Nigel Tao <nigeltao@golang.org> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org>
2019-03-24 23:21:38 +01:00
{1e23, 'e', 17, "9.99999999999999916e+22"},
{1e23, 'f', 17, "99999999999999991611392.00000000000000000"},
{1e23, 'g', 17, "9.9999999999999992e+22"},
{1e23, 'e', -1, "1e+23"},
{1e23, 'f', -1, "100000000000000000000000"},
{1e23, 'g', -1, "1e+23"},
{below1e23, 'e', 17, "9.99999999999999748e+22"},
{below1e23, 'f', 17, "99999999999999974834176.00000000000000000"},
{below1e23, 'g', 17, "9.9999999999999975e+22"},
{below1e23, 'e', -1, "9.999999999999997e+22"},
{below1e23, 'f', -1, "99999999999999970000000"},
{below1e23, 'g', -1, "9.999999999999997e+22"},
{above1e23, 'e', 17, "1.00000000000000008e+23"},
{above1e23, 'f', 17, "100000000000000008388608.00000000000000000"},
{above1e23, 'g', 17, "1.0000000000000001e+23"},
{above1e23, 'e', -1, "1.0000000000000001e+23"},
{above1e23, 'f', -1, "100000000000000010000000"},
{above1e23, 'g', -1, "1.0000000000000001e+23"},
{fdiv(5e-304, 1e20), 'g', -1, "5e-324"}, // avoid constant arithmetic
{fdiv(-5e-304, 1e20), 'g', -1, "-5e-324"}, // avoid constant arithmetic
{32, 'g', -1, "32"},
{32, 'g', 0, "3e+01"},
{100, 'x', -1, "0x1.9p+06"},
{100, 'y', -1, "%y"},
{math.NaN(), 'g', -1, "NaN"},
{-math.NaN(), 'g', -1, "NaN"},
{math.Inf(0), 'g', -1, "+Inf"},
{math.Inf(-1), 'g', -1, "-Inf"},
{-math.Inf(0), 'g', -1, "-Inf"},
{-1, 'b', -1, "-4503599627370496p-52"},
// fixed bugs
{0.9, 'f', 1, "0.9"},
{0.09, 'f', 1, "0.1"},
{0.0999, 'f', 1, "0.1"},
{0.05, 'f', 1, "0.1"},
{0.05, 'f', 0, "0"},
{0.5, 'f', 1, "0.5"},
{0.5, 'f', 0, "0"},
{1.5, 'f', 0, "2"},
// https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
{2.2250738585072012e-308, 'g', -1, "2.2250738585072014e-308"},
// https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
{2.2250738585072011e-308, 'g', -1, "2.225073858507201e-308"},
// Issue 2625.
{383260575764816448, 'f', 0, "383260575764816448"},
{383260575764816448, 'g', -1, "3.8326057576481645e+17"},
strconv: fix rounding in FormatFloat fallback path Float formatting uses a multiprecision fallback path where Grisu3 algorithm fails. This has a bug during the rounding phase: the difference between the decimal value and the upper bound is examined byte-by-byte and doesn't properly handle the case where the first divergence has a difference of 1. For instance (using an example from #29491), for the number 498484681984085570, roundShortest examines the three decimal values: lower: 498484681984085536 d: 498484681984085568 upper: 498484681984085600 After examining the 16th digit, we know that rounding d up will fall within the bounds unless all remaining digits of d are 9 and all remaining digits of upper are 0: d: ...855xx upper: ...856xx However, the loop forgets that d and upper have already diverged and then on the next iteration sees that the 17th digit of d is actually lower than the 17th digit of upper and decides that we still can't round up: d: ...8556x upper: ...8560x Thus the original value is incorrectly rounded down to 498484681984085560 instead of the closer (and equally short) 498484681984085570. Thanks to Brian Kessler for diagnosing this bug. Fix it by remembering when we've seen divergence in previous digits. This CL also fixes another bug in the same loop: for some inputs, the decimal value d or the lower bound may have fewer digits than the upper bound, yet the iteration through the digits starts at i=0 for each of them. For instance, given the float64 value 1e23, we have d: 99999999999999991611392 upper: 100000000000000000000000 but the loop starts by comparing '9' to '1' rather than '0' to '1'. I haven't found any cases where this second bug causes incorrect output because when the digit comparison fails on the first loop iteration the upper bound always has more nonzero digits (i.e., the expression 'i+1 < upper.nd' is always true). Fixes #29491 Change-Id: I58856a7a2e47935ec2f233d9f717ef15c78bb2d0 Reviewed-on: https://go-review.googlesource.com/c/go/+/157697 Run-TryBot: Caleb Spare <cespare@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rémy Oudompheng <remyoudompheng@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-01-12 14:29:08 -08:00
// Issue 29491.
{498484681984085570, 'f', -1, "498484681984085570"},
{-5.8339553793802237e+23, 'g', -1, "-5.8339553793802237e+23"},
// Issue 52187
{123.45, '?', 0, "%?"},
{123.45, '?', 1, "%?"},
{123.45, '?', -1, "%?"},
// rounding
{2.275555555555555, 'x', -1, "0x1.23456789abcdep+01"},
{2.275555555555555, 'x', 0, "0x1p+01"},
{2.275555555555555, 'x', 2, "0x1.23p+01"},
{2.275555555555555, 'x', 16, "0x1.23456789abcde000p+01"},
{2.275555555555555, 'x', 21, "0x1.23456789abcde00000000p+01"},
{2.2755555510520935, 'x', -1, "0x1.2345678p+01"},
{2.2755555510520935, 'x', 6, "0x1.234568p+01"},
{2.275555431842804, 'x', -1, "0x1.2345668p+01"},
{2.275555431842804, 'x', 6, "0x1.234566p+01"},
{3.999969482421875, 'x', -1, "0x1.ffffp+01"},
{3.999969482421875, 'x', 4, "0x1.ffffp+01"},
{3.999969482421875, 'x', 3, "0x1.000p+02"},
{3.999969482421875, 'x', 2, "0x1.00p+02"},
{3.999969482421875, 'x', 1, "0x1.0p+02"},
{3.999969482421875, 'x', 0, "0x1p+02"},
// Cases that Java once mishandled, from David Chase.
{1.801439850948199e+16, 'g', -1, "1.801439850948199e+16"},
{5.960464477539063e-08, 'g', -1, "5.960464477539063e-08"},
{1.012e-320, 'g', -1, "1.012e-320"},
internal/strconv: extract fixed-precision ftoa from ftoaryu.go The fixed-precision ftoa algorithm is not actually documented in the Ryū paper, and it is fairly straightforward: multiply by a power of 10 to get an integer that contains the digits we need. There is also no need for separate float32 and float64 implementations. This CL implements a new fixedFtoa, separate from Ryū. The overall algorithm is the same, but the new code is simpler, faster, and better documented. Now ftoaryu.go is only about shortest-output formatting, so if and when yet another algorithm comes along, it will be clearer what should be replaced (all of ftoaryu.go) and what should not (all of ftoafixed.go). benchmark \ host linux-arm64 local linux-amd64 s7 linux-386 s7:GOARCH=386 vs base vs base vs base vs base vs base vs base AppendFloat/Decimal -0.18% ~ ~ -0.68% +0.49% -0.79% AppendFloat/Float +0.09% ~ +1.50% +0.84% -0.37% -0.69% AppendFloat/Exp -0.51% ~ ~ +1.20% -1.27% -1.01% AppendFloat/NegExp -1.01% ~ +3.43% +1.35% -2.33% ~ AppendFloat/LongExp -1.22% +0.77% ~ ~ -1.48% ~ AppendFloat/Big -2.07% ~ -2.07% -1.97% -2.89% -2.93% AppendFloat/BinaryExp -0.28% +1.06% ~ +1.35% -0.64% -1.64% AppendFloat/32Integer ~ ~ ~ -0.79% ~ -0.66% AppendFloat/32ExactFraction -0.50% ~ +5.69% ~ -1.24% +0.69% AppendFloat/32Point ~ -1.19% +2.59% +1.03% -1.37% +0.80% AppendFloat/32Exp -3.39% -2.79% -8.36% -0.94% -5.72% -5.92% AppendFloat/32NegExp -0.63% ~ ~ +0.98% -1.34% -0.73% AppendFloat/32Shortest -1.00% +1.36% +2.94% ~ ~ ~ AppendFloat/32Fixed8Hard -5.91% -12.45% -6.62% ~ +18.46% +11.61% AppendFloat/32Fixed9Hard -6.53% -11.35% -6.01% -0.97% -18.31% -9.16% AppendFloat/64Fixed1 -13.84% -16.90% -13.13% -10.71% -24.52% -18.94% AppendFloat/64Fixed2 -11.12% -16.97% -12.13% -9.88% -22.73% -15.48% AppendFloat/64Fixed2.5 -21.98% -20.75% -19.08% -14.74% -28.11% -24.92% AppendFloat/64Fixed3 -11.53% -16.21% -10.75% -7.53% -23.11% -15.78% AppendFloat/64Fixed4 -12.89% -12.36% -11.07% -9.79% -14.51% -13.44% AppendFloat/64Fixed5Hard -47.62% -38.59% -40.83% -37.06% -60.51% -55.29% AppendFloat/64Fixed12 -7.40% ~ -8.56% -4.31% -13.82% -8.61% AppendFloat/64Fixed16 -9.10% -8.95% -6.92% -3.92% -12.99% -9.03% AppendFloat/64Fixed12Hard -9.14% -5.24% -6.23% -4.82% -13.58% -8.99% AppendFloat/64Fixed17Hard -6.80% ~ -4.03% -2.84% -19.81% -10.27% AppendFloat/64Fixed18Hard -0.12% ~ ~ ~ ~ ~ AppendFloat/64FixedF1 ~ ~ ~ ~ -0.40% +2.72% AppendFloat/64FixedF2 -0.18% ~ -1.98% -0.95% ~ +1.25% AppendFloat/64FixedF3 -0.29% ~ ~ ~ ~ +1.22% AppendFloat/Slowpath64 -1.16% ~ ~ ~ ~ -2.16% AppendFloat/SlowpathDenormal64 -1.09% ~ ~ -0.88% -0.83% ~ host: linux-arm64 goos: linux goarch: arm64 pkg: internal/strconv cpu: unknown │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-8 60.35n ± 0% 60.24n ± 0% -0.18% (p=0.000 n=20) AppendFloat/Float-8 88.83n ± 0% 88.91n ± 0% +0.09% (p=0.000 n=20) AppendFloat/Exp-8 93.55n ± 0% 93.06n ± 0% -0.51% (p=0.000 n=20) AppendFloat/NegExp-8 94.01n ± 0% 93.06n ± 0% -1.01% (p=0.000 n=20) AppendFloat/LongExp-8 101.00n ± 0% 99.77n ± 0% -1.22% (p=0.000 n=20) AppendFloat/Big-8 106.1n ± 0% 103.9n ± 0% -2.07% (p=0.000 n=20) AppendFloat/BinaryExp-8 47.48n ± 0% 47.35n ± 0% -0.28% (p=0.000 n=20) AppendFloat/32Integer-8 60.45n ± 0% 60.43n ± 0% ~ (p=0.150 n=20) AppendFloat/32ExactFraction-8 86.65n ± 0% 86.22n ± 0% -0.50% (p=0.000 n=20) AppendFloat/32Point-8 83.26n ± 0% 83.21n ± 0% ~ (p=0.046 n=20) AppendFloat/32Exp-8 92.55n ± 0% 89.42n ± 0% -3.39% (p=0.000 n=20) AppendFloat/32NegExp-8 87.89n ± 0% 87.34n ± 0% -0.63% (p=0.000 n=20) AppendFloat/32Shortest-8 77.05n ± 0% 76.28n ± 0% -1.00% (p=0.000 n=20) AppendFloat/32Fixed8Hard-8 55.73n ± 0% 52.44n ± 0% -5.91% (p=0.000 n=20) AppendFloat/32Fixed9Hard-8 64.80n ± 0% 60.57n ± 0% -6.53% (p=0.000 n=20) AppendFloat/64Fixed1-8 53.72n ± 0% 46.29n ± 0% -13.84% (p=0.000 n=20) AppendFloat/64Fixed2-8 52.64n ± 0% 46.79n ± 0% -11.12% (p=0.000 n=20) AppendFloat/64Fixed2.5-8 56.01n ± 0% 43.70n ± 0% -21.98% (p=0.000 n=20) AppendFloat/64Fixed3-8 53.38n ± 0% 47.23n ± 0% -11.53% (p=0.000 n=20) AppendFloat/64Fixed4-8 50.62n ± 0% 44.10n ± 0% -12.89% (p=0.000 n=20) AppendFloat/64Fixed5Hard-8 98.94n ± 0% 51.82n ± 0% -47.62% (p=0.000 n=20) AppendFloat/64Fixed12-8 84.70n ± 0% 78.44n ± 0% -7.40% (p=0.000 n=20) AppendFloat/64Fixed16-8 71.68n ± 0% 65.16n ± 0% -9.10% (p=0.000 n=20) AppendFloat/64Fixed12Hard-8 68.41n ± 0% 62.16n ± 0% -9.14% (p=0.000 n=20) AppendFloat/64Fixed17Hard-8 79.31n ± 0% 73.92n ± 0% -6.80% (p=0.000 n=20) AppendFloat/64Fixed18Hard-8 4.290µ ± 0% 4.285µ ± 0% -0.12% (p=0.000 n=20) AppendFloat/64FixedF1-8 216.0n ± 0% 216.1n ± 0% ~ (p=0.090 n=20) AppendFloat/64FixedF2-8 228.2n ± 0% 227.8n ± 0% -0.18% (p=0.000 n=20) AppendFloat/64FixedF3-8 208.8n ± 0% 208.2n ± 0% -0.29% (p=0.000 n=20) AppendFloat/Slowpath64-8 98.56n ± 0% 97.42n ± 0% -1.16% (p=0.000 n=20) AppendFloat/SlowpathDenormal64-8 95.81n ± 0% 94.77n ± 0% -1.09% (p=0.000 n=20) geomean 93.81n 87.87n -6.33% host: local goos: darwin cpu: Apple M3 Pro │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-12 21.14n ± 0% 21.15n ± 0% ~ (p=0.963 n=20) AppendFloat/Float-12 32.48n ± 1% 32.43n ± 0% ~ (p=0.358 n=20) AppendFloat/Exp-12 31.85n ± 0% 31.94n ± 1% ~ (p=0.634 n=20) AppendFloat/NegExp-12 31.75n ± 0% 32.04n ± 0% ~ (p=0.004 n=20) AppendFloat/LongExp-12 33.55n ± 0% 33.81n ± 0% +0.77% (p=0.000 n=20) AppendFloat/Big-12 35.62n ± 1% 35.73n ± 1% ~ (p=0.888 n=20) AppendFloat/BinaryExp-12 19.26n ± 0% 19.46n ± 1% +1.06% (p=0.000 n=20) AppendFloat/32Integer-12 21.41n ± 0% 21.46n ± 1% ~ (p=0.733 n=20) AppendFloat/32ExactFraction-12 31.23n ± 1% 31.30n ± 1% ~ (p=0.857 n=20) AppendFloat/32Point-12 31.39n ± 1% 31.02n ± 0% -1.19% (p=0.000 n=20) AppendFloat/32Exp-12 32.42n ± 1% 31.52n ± 1% -2.79% (p=0.000 n=20) AppendFloat/32NegExp-12 30.66n ± 1% 30.66n ± 1% ~ (p=0.380 n=20) AppendFloat/32Shortest-12 26.88n ± 1% 27.25n ± 1% +1.36% (p=0.000 n=20) AppendFloat/32Fixed8Hard-12 19.52n ± 0% 17.09n ± 1% -12.45% (p=0.000 n=20) AppendFloat/32Fixed9Hard-12 21.55n ± 2% 19.11n ± 1% -11.35% (p=0.000 n=20) AppendFloat/64Fixed1-12 18.64n ± 0% 15.49n ± 0% -16.90% (p=0.000 n=20) AppendFloat/64Fixed2-12 18.65n ± 0% 15.49n ± 0% -16.97% (p=0.000 n=20) AppendFloat/64Fixed2.5-12 19.23n ± 1% 15.24n ± 0% -20.75% (p=0.000 n=20) AppendFloat/64Fixed3-12 18.61n ± 0% 15.59n ± 1% -16.21% (p=0.000 n=20) AppendFloat/64Fixed4-12 17.55n ± 1% 15.38n ± 0% -12.36% (p=0.000 n=20) AppendFloat/64Fixed5Hard-12 29.27n ± 1% 17.97n ± 0% -38.59% (p=0.000 n=20) AppendFloat/64Fixed12-12 28.26n ± 1% 28.17n ± 10% ~ (p=0.941 n=20) AppendFloat/64Fixed16-12 23.56n ± 0% 21.46n ± 0% -8.95% (p=0.000 n=20) AppendFloat/64Fixed12Hard-12 21.85n ± 2% 20.70n ± 1% -5.24% (p=0.000 n=20) AppendFloat/64Fixed17Hard-12 26.91n ± 1% 27.10n ± 0% ~ (p=0.059 n=20) AppendFloat/64Fixed18Hard-12 2.197µ ± 1% 2.169µ ± 1% ~ (p=0.013 n=20) AppendFloat/64FixedF1-12 103.7n ± 1% 103.3n ± 0% ~ (p=0.035 n=20) AppendFloat/64FixedF2-12 114.8n ± 1% 114.1n ± 1% ~ (p=0.234 n=20) AppendFloat/64FixedF3-12 107.8n ± 1% 107.1n ± 1% ~ (p=0.180 n=20) AppendFloat/Slowpath64-12 32.05n ± 1% 32.00n ± 0% ~ (p=0.952 n=20) AppendFloat/SlowpathDenormal64-12 29.98n ± 1% 30.20n ± 0% ~ (p=0.004 n=20) geomean 33.83n 31.91n -5.68% host: linux-amd64 goos: linux goarch: amd64 cpu: Intel(R) Xeon(R) CPU @ 2.30GHz │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-16 64.00n ± 1% 63.67n ± 1% ~ (p=0.784 n=20) AppendFloat/Float-16 95.99n ± 1% 97.42n ± 1% +1.50% (p=0.000 n=20) AppendFloat/Exp-16 97.59n ± 1% 97.72n ± 1% ~ (p=0.984 n=20) AppendFloat/NegExp-16 97.80n ± 1% 101.15n ± 1% +3.43% (p=0.000 n=20) AppendFloat/LongExp-16 103.1n ± 1% 104.5n ± 1% ~ (p=0.006 n=20) AppendFloat/Big-16 110.8n ± 1% 108.5n ± 1% -2.07% (p=0.000 n=20) AppendFloat/BinaryExp-16 47.82n ± 1% 47.33n ± 1% ~ (p=0.007 n=20) AppendFloat/32Integer-16 63.65n ± 1% 63.51n ± 0% ~ (p=0.560 n=20) AppendFloat/32ExactFraction-16 91.81n ± 1% 97.03n ± 1% +5.69% (p=0.000 n=20) AppendFloat/32Point-16 89.84n ± 1% 92.16n ± 1% +2.59% (p=0.000 n=20) AppendFloat/32Exp-16 103.80n ± 1% 95.12n ± 1% -8.36% (p=0.000 n=20) AppendFloat/32NegExp-16 93.70n ± 1% 94.87n ± 1% ~ (p=0.003 n=20) AppendFloat/32Shortest-16 83.98n ± 1% 86.45n ± 1% +2.94% (p=0.000 n=20) AppendFloat/32Fixed8Hard-16 61.91n ± 1% 57.81n ± 1% -6.62% (p=0.000 n=20) AppendFloat/32Fixed9Hard-16 71.08n ± 0% 66.81n ± 1% -6.01% (p=0.000 n=20) AppendFloat/64Fixed1-16 59.27n ± 2% 51.49n ± 1% -13.13% (p=0.000 n=20) AppendFloat/64Fixed2-16 57.89n ± 1% 50.87n ± 1% -12.13% (p=0.000 n=20) AppendFloat/64Fixed2.5-16 61.04n ± 1% 49.40n ± 1% -19.08% (p=0.000 n=20) AppendFloat/64Fixed3-16 58.42n ± 1% 52.14n ± 1% -10.75% (p=0.000 n=20) AppendFloat/64Fixed4-16 56.52n ± 1% 50.27n ± 1% -11.07% (p=0.000 n=20) AppendFloat/64Fixed5Hard-16 97.79n ± 1% 57.86n ± 1% -40.83% (p=0.000 n=20) AppendFloat/64Fixed12-16 90.78n ± 1% 83.01n ± 1% -8.56% (p=0.000 n=20) AppendFloat/64Fixed16-16 76.11n ± 1% 70.84n ± 0% -6.92% (p=0.000 n=20) AppendFloat/64Fixed12Hard-16 73.56n ± 1% 68.98n ± 2% -6.23% (p=0.000 n=20) AppendFloat/64Fixed17Hard-16 83.20n ± 1% 79.85n ± 1% -4.03% (p=0.000 n=20) AppendFloat/64Fixed18Hard-16 4.947µ ± 1% 4.915µ ± 1% ~ (p=0.229 n=20) AppendFloat/64FixedF1-16 242.4n ± 1% 239.4n ± 1% ~ (p=0.038 n=20) AppendFloat/64FixedF2-16 257.7n ± 2% 252.6n ± 1% -1.98% (p=0.000 n=20) AppendFloat/64FixedF3-16 237.5n ± 0% 237.5n ± 1% ~ (p=0.440 n=20) AppendFloat/Slowpath64-16 99.75n ± 1% 99.78n ± 1% ~ (p=0.995 n=20) AppendFloat/SlowpathDenormal64-16 97.41n ± 1% 98.20n ± 1% ~ (p=0.006 n=20) geomean 100.7n 95.60n -5.05% host: s7 cpu: AMD Ryzen 9 7950X 16-Core Processor │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-32 22.19n ± 0% 22.04n ± 0% -0.68% (p=0.000 n=20) AppendFloat/Float-32 34.59n ± 0% 34.88n ± 0% +0.84% (p=0.000 n=20) AppendFloat/Exp-32 34.47n ± 0% 34.88n ± 0% +1.20% (p=0.000 n=20) AppendFloat/NegExp-32 34.85n ± 0% 35.32n ± 0% +1.35% (p=0.000 n=20) AppendFloat/LongExp-32 37.23n ± 0% 37.09n ± 0% ~ (p=0.003 n=20) AppendFloat/Big-32 39.27n ± 0% 38.50n ± 0% -1.97% (p=0.000 n=20) AppendFloat/BinaryExp-32 17.38n ± 0% 17.61n ± 0% +1.35% (p=0.000 n=20) AppendFloat/32Integer-32 22.26n ± 0% 22.08n ± 0% -0.79% (p=0.000 n=20) AppendFloat/32ExactFraction-32 32.82n ± 0% 32.91n ± 0% ~ (p=0.018 n=20) AppendFloat/32Point-32 32.88n ± 0% 33.22n ± 0% +1.03% (p=0.000 n=20) AppendFloat/32Exp-32 34.95n ± 0% 34.62n ± 0% -0.94% (p=0.000 n=20) AppendFloat/32NegExp-32 33.23n ± 0% 33.55n ± 0% +0.98% (p=0.000 n=20) AppendFloat/32Shortest-32 30.19n ± 0% 30.12n ± 0% ~ (p=0.122 n=20) AppendFloat/32Fixed8Hard-32 22.94n ± 0% 22.88n ± 0% ~ (p=0.124 n=20) AppendFloat/32Fixed9Hard-32 26.20n ± 0% 25.94n ± 1% -0.97% (p=0.000 n=20) AppendFloat/64Fixed1-32 21.10n ± 0% 18.84n ± 0% -10.71% (p=0.000 n=20) AppendFloat/64Fixed2-32 20.75n ± 0% 18.70n ± 0% -9.88% (p=0.000 n=20) AppendFloat/64Fixed2.5-32 21.07n ± 0% 17.96n ± 0% -14.74% (p=0.000 n=20) AppendFloat/64Fixed3-32 21.24n ± 0% 19.64n ± 0% -7.53% (p=0.000 n=20) AppendFloat/64Fixed4-32 20.63n ± 0% 18.61n ± 0% -9.79% (p=0.000 n=20) AppendFloat/64Fixed5Hard-32 34.48n ± 0% 21.70n ± 0% -37.06% (p=0.000 n=20) AppendFloat/64Fixed12-32 32.26n ± 0% 30.87n ± 1% -4.31% (p=0.000 n=20) AppendFloat/64Fixed16-32 27.95n ± 0% 26.86n ± 0% -3.92% (p=0.000 n=20) AppendFloat/64Fixed12Hard-32 27.30n ± 0% 25.98n ± 1% -4.82% (p=0.000 n=20) AppendFloat/64Fixed17Hard-32 30.80n ± 0% 29.93n ± 0% -2.84% (p=0.000 n=20) AppendFloat/64Fixed18Hard-32 1.833µ ± 0% 1.831µ ± 0% ~ (p=0.663 n=20) AppendFloat/64FixedF1-32 83.42n ± 1% 84.00n ± 1% ~ (p=0.003 n=20) AppendFloat/64FixedF2-32 90.10n ± 0% 89.23n ± 1% -0.95% (p=0.001 n=20) AppendFloat/64FixedF3-32 84.42n ± 1% 84.39n ± 0% ~ (p=0.878 n=20) AppendFloat/Slowpath64-32 35.72n ± 0% 35.59n ± 0% ~ (p=0.007 n=20) AppendFloat/SlowpathDenormal64-32 35.36n ± 0% 35.05n ± 0% -0.88% (p=0.000 n=20) geomean 36.05n 34.69n -3.77% host: linux-386 goarch: 386 cpu: Intel(R) Xeon(R) CPU @ 2.30GHz │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-16 132.8n ± 0% 133.5n ± 0% +0.49% (p=0.001 n=20) AppendFloat/Float-16 242.6n ± 0% 241.7n ± 0% -0.37% (p=0.000 n=20) AppendFloat/Exp-16 252.2n ± 0% 249.1n ± 0% -1.27% (p=0.000 n=20) AppendFloat/NegExp-16 253.6n ± 0% 247.7n ± 0% -2.33% (p=0.000 n=20) AppendFloat/LongExp-16 260.9n ± 0% 257.1n ± 0% -1.48% (p=0.000 n=20) AppendFloat/Big-16 293.7n ± 0% 285.2n ± 0% -2.89% (p=0.000 n=20) AppendFloat/BinaryExp-16 89.63n ± 1% 89.06n ± 0% -0.64% (p=0.000 n=20) AppendFloat/32Integer-16 132.6n ± 0% 133.2n ± 0% ~ (p=0.016 n=20) AppendFloat/32ExactFraction-16 216.9n ± 0% 214.2n ± 0% -1.24% (p=0.000 n=20) AppendFloat/32Point-16 205.0n ± 0% 202.2n ± 0% -1.37% (p=0.000 n=20) AppendFloat/32Exp-16 250.2n ± 0% 235.9n ± 0% -5.72% (p=0.000 n=20) AppendFloat/32NegExp-16 213.5n ± 0% 210.6n ± 0% -1.34% (p=0.000 n=20) AppendFloat/32Shortest-16 198.3n ± 0% 197.8n ± 0% ~ (p=0.147 n=20) AppendFloat/32Fixed8Hard-16 114.9n ± 1% 136.0n ± 1% +18.46% (p=0.000 n=20) AppendFloat/32Fixed9Hard-16 189.8n ± 0% 155.0n ± 1% -18.31% (p=0.000 n=20) AppendFloat/64Fixed1-16 175.8n ± 0% 132.7n ± 0% -24.52% (p=0.000 n=20) AppendFloat/64Fixed2-16 166.6n ± 0% 128.7n ± 0% -22.73% (p=0.000 n=20) AppendFloat/64Fixed2.5-16 176.5n ± 0% 126.8n ± 0% -28.11% (p=0.000 n=20) AppendFloat/64Fixed3-16 165.3n ± 0% 127.1n ± 0% -23.11% (p=0.000 n=20) AppendFloat/64Fixed4-16 141.3n ± 0% 120.8n ± 1% -14.51% (p=0.000 n=20) AppendFloat/64Fixed5Hard-16 344.6n ± 0% 136.0n ± 0% -60.51% (p=0.000 n=20) AppendFloat/64Fixed12-16 184.2n ± 0% 158.7n ± 0% -13.82% (p=0.000 n=20) AppendFloat/64Fixed16-16 174.0n ± 0% 151.3n ± 0% -12.99% (p=0.000 n=20) AppendFloat/64Fixed12Hard-16 169.7n ± 0% 146.7n ± 0% -13.58% (p=0.000 n=20) AppendFloat/64Fixed17Hard-16 207.7n ± 0% 166.6n ± 0% -19.81% (p=0.000 n=20) AppendFloat/64Fixed18Hard-16 10.66µ ± 0% 10.63µ ± 0% ~ (p=0.030 n=20) AppendFloat/64FixedF1-16 615.9n ± 0% 613.5n ± 0% -0.40% (p=0.000 n=20) AppendFloat/64FixedF2-16 846.6n ± 0% 847.4n ± 0% ~ (p=0.551 n=20) AppendFloat/64FixedF3-16 609.9n ± 0% 609.5n ± 0% ~ (p=0.213 n=20) AppendFloat/Slowpath64-16 254.1n ± 0% 252.6n ± 1% ~ (p=0.048 n=20) AppendFloat/SlowpathDenormal64-16 251.5n ± 0% 249.4n ± 0% -0.83% (p=0.000 n=20) geomean 249.2n 225.4n -9.54% host: s7:GOARCH=386 cpu: AMD Ryzen 9 7950X 16-Core Processor │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-32 42.65n ± 0% 42.31n ± 0% -0.79% (p=0.000 n=20) AppendFloat/Float-32 71.56n ± 0% 71.06n ± 0% -0.69% (p=0.000 n=20) AppendFloat/Exp-32 75.61n ± 1% 74.85n ± 1% -1.01% (p=0.000 n=20) AppendFloat/NegExp-32 74.36n ± 0% 74.30n ± 0% ~ (p=0.482 n=20) AppendFloat/LongExp-32 75.82n ± 0% 75.73n ± 0% ~ (p=0.490 n=20) AppendFloat/Big-32 85.10n ± 0% 82.61n ± 0% -2.93% (p=0.000 n=20) AppendFloat/BinaryExp-32 33.02n ± 0% 32.48n ± 1% -1.64% (p=0.000 n=20) AppendFloat/32Integer-32 41.54n ± 1% 41.27n ± 1% -0.66% (p=0.000 n=20) AppendFloat/32ExactFraction-32 62.48n ± 0% 62.91n ± 0% +0.69% (p=0.000 n=20) AppendFloat/32Point-32 60.17n ± 0% 60.65n ± 0% +0.80% (p=0.000 n=20) AppendFloat/32Exp-32 73.34n ± 0% 68.99n ± 0% -5.92% (p=0.000 n=20) AppendFloat/32NegExp-32 63.29n ± 0% 62.83n ± 0% -0.73% (p=0.000 n=20) AppendFloat/32Shortest-32 58.97n ± 0% 59.07n ± 0% ~ (p=0.029 n=20) AppendFloat/32Fixed8Hard-32 37.42n ± 0% 41.76n ± 1% +11.61% (p=0.000 n=20) AppendFloat/32Fixed9Hard-32 55.18n ± 0% 50.13n ± 1% -9.16% (p=0.000 n=20) AppendFloat/64Fixed1-32 50.89n ± 1% 41.25n ± 0% -18.94% (p=0.000 n=20) AppendFloat/64Fixed2-32 48.33n ± 1% 40.85n ± 1% -15.48% (p=0.000 n=20) AppendFloat/64Fixed2.5-32 52.46n ± 0% 39.39n ± 0% -24.92% (p=0.000 n=20) AppendFloat/64Fixed3-32 48.28n ± 1% 40.66n ± 0% -15.78% (p=0.000 n=20) AppendFloat/64Fixed4-32 44.57n ± 0% 38.58n ± 0% -13.44% (p=0.000 n=20) AppendFloat/64Fixed5Hard-32 96.16n ± 0% 42.99n ± 1% -55.29% (p=0.000 n=20) AppendFloat/64Fixed12-32 56.84n ± 0% 51.95n ± 1% -8.61% (p=0.000 n=20) AppendFloat/64Fixed16-32 54.23n ± 0% 49.33n ± 0% -9.03% (p=0.000 n=20) AppendFloat/64Fixed12Hard-32 53.47n ± 0% 48.67n ± 0% -8.99% (p=0.000 n=20) AppendFloat/64Fixed17Hard-32 61.76n ± 0% 55.42n ± 1% -10.27% (p=0.000 n=20) AppendFloat/64Fixed18Hard-32 3.998µ ± 1% 4.001µ ± 0% ~ (p=0.449 n=20) AppendFloat/64FixedF1-32 161.8n ± 0% 166.2n ± 1% +2.72% (p=0.000 n=20) AppendFloat/64FixedF2-32 223.4n ± 2% 226.2n ± 1% +1.25% (p=0.000 n=20) AppendFloat/64FixedF3-32 159.6n ± 0% 161.6n ± 1% +1.22% (p=0.000 n=20) AppendFloat/Slowpath64-32 76.69n ± 0% 75.03n ± 0% -2.16% (p=0.000 n=20) AppendFloat/SlowpathDenormal64-32 75.02n ± 0% 74.36n ± 1% ~ (p=0.003 n=20) geomean 74.66n 69.39n -7.06% Change-Id: I9db46471a93bd2aab3c2796e563d154cb531d4cb Reviewed-on: https://go-review.googlesource.com/c/go/+/717182 Reviewed-by: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Russ Cox <rsc@golang.org>
2025-11-01 09:41:40 -04:00
// Cases from TestFtoaRandom that caught bugs in fixedFtoa.
{8177880169308380. * (1 << 1), 'e', 14, "1.63557603386168e+16"},
{8393378656576888. * (1 << 1), 'e', 15, "1.678675731315378e+16"},
{8738676561280626. * (1 << 4), 'e', 16, "1.3981882498049002e+17"},
{8291032395191335. / (1 << 30), 'e', 5, "7.72163e+06"},
// Exercise divisiblePow5 case in fixedFtoa
{2384185791015625. * (1 << 12), 'e', 5, "9.76562e+18"},
{2384185791015625. * (1 << 13), 'e', 5, "1.95312e+19"},
}
2009-01-20 14:40:40 -08:00
func TestFtoa(t *testing.T) {
for i := 0; i < len(ftoatests); i++ {
test := &ftoatests[i]
s := FormatFloat(test.f, test.fmt, test.prec, 64)
if s != test.s {
t.Error("testN=64", test.f, string(test.fmt), test.prec, "want", test.s, "got", s)
}
x := AppendFloat([]byte("abc"), test.f, test.fmt, test.prec, 64)
if string(x) != "abc"+test.s {
t.Error("AppendFloat testN=64", test.f, string(test.fmt), test.prec, "want", "abc"+test.s, "got", string(x))
}
if float64(float32(test.f)) == test.f && test.fmt != 'b' {
test_s := test.s
if test.f == 5.960464477539063e-08 {
// This test is an exact float32 but asking for float64 precision in the string.
// (All our other float64-only tests fail to exactness check above.)
test_s = "5.9604645e-08"
continue
}
s := FormatFloat(test.f, test.fmt, test.prec, 32)
if s != test.s {
t.Error("testN=32", test.f, string(test.fmt), test.prec, "want", test_s, "got", s)
}
x := AppendFloat([]byte("abc"), test.f, test.fmt, test.prec, 32)
if string(x) != "abc"+test_s {
t.Error("AppendFloat testN=32", test.f, string(test.fmt), test.prec, "want", "abc"+test_s, "got", string(x))
}
}
}
}
strconv: Implement Ryū algorithm for ftoa shortest mode This patch implements the algorithm from Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369) for formatting floating-point numbers with a fixed number of decimal digits. It is not a direct translation of the reference C implementation but still follows the original paper. In particular, it uses full 128-bit powers of 10, which allows for more precision in the other modes (fixed ftoa, atof). name old time/op new time/op delta AppendFloat/Decimal-4 49.6ns ± 3% 59.3ns ± 0% +19.59% (p=0.008 n=5+5) AppendFloat/Float-4 122ns ± 1% 91ns ± 1% -25.92% (p=0.008 n=5+5) AppendFloat/Exp-4 89.3ns ± 1% 100.0ns ± 1% +11.98% (p=0.008 n=5+5) AppendFloat/NegExp-4 88.3ns ± 2% 97.1ns ± 1% +9.87% (p=0.008 n=5+5) AppendFloat/LongExp-4 143ns ± 2% 103ns ± 0% -28.17% (p=0.016 n=5+4) AppendFloat/Big-4 144ns ± 1% 110ns ± 1% -23.26% (p=0.008 n=5+5) AppendFloat/BinaryExp-4 46.2ns ± 2% 46.0ns ± 1% ~ (p=0.603 n=5+5) AppendFloat/32Integer-4 49.1ns ± 1% 58.7ns ± 1% +19.57% (p=0.008 n=5+5) AppendFloat/32ExactFraction-4 95.6ns ± 1% 88.6ns ± 1% -7.30% (p=0.008 n=5+5) AppendFloat/32Point-4 122ns ± 1% 87ns ± 1% -28.63% (p=0.008 n=5+5) AppendFloat/32Exp-4 88.6ns ± 2% 95.0ns ± 1% +7.29% (p=0.008 n=5+5) AppendFloat/32NegExp-4 87.2ns ± 1% 91.3ns ± 1% +4.63% (p=0.008 n=5+5) AppendFloat/32Shortest-4 107ns ± 1% 82ns ± 0% -24.08% (p=0.008 n=5+5) AppendFloat/Slowpath64-4 1.00µs ± 1% 0.10µs ± 0% -89.92% (p=0.016 n=5+4) AppendFloat/SlowpathDenormal64-4 34.1µs ± 3% 0.1µs ± 1% -99.72% (p=0.008 n=5+5) Fixes #15672 Change-Id: Ib90dfa245f62490a6666671896013cf3f9a1fb22 Reviewed-on: https://go-review.googlesource.com/c/go/+/170080 Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Nigel Tao <nigeltao@golang.org> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Nigel Tao <nigeltao@golang.org>
2019-03-27 06:55:52 +01:00
func TestFtoaPowersOfTwo(t *testing.T) {
for exp := -2048; exp <= 2048; exp++ {
f := math.Ldexp(1, exp)
if !math.IsInf(f, 0) {
s := FormatFloat(f, 'e', -1, 64)
if x, _ := ParseFloat(s, 64); x != f {
t.Errorf("failed roundtrip %v => %s => %v", f, s, x)
}
}
f32 := float32(f)
if !math.IsInf(float64(f32), 0) {
s := FormatFloat(float64(f32), 'e', -1, 32)
if x, _ := ParseFloat(s, 32); float32(x) != f32 {
t.Errorf("failed roundtrip %v => %s => %v", f32, s, float32(x))
}
}
}
}
func TestFtoaRandom(t *testing.T) {
N := int(1e4)
if testing.Short() {
N = 100
}
t.Logf("testing %d random numbers with fast and slow FormatFloat", N)
for i := 0; i < N; i++ {
bits := uint64(rand.Uint32())<<32 | uint64(rand.Uint32())
x := math.Float64frombits(bits)
shortFast := FormatFloat(x, 'g', -1, 64)
SetOptimize(false)
shortSlow := FormatFloat(x, 'g', -1, 64)
SetOptimize(true)
if shortSlow != shortFast {
t.Errorf("%b printed as %s, want %s", x, shortFast, shortSlow)
}
prec := rand.Intn(12) + 5
shortFast = FormatFloat(x, 'e', prec, 64)
SetOptimize(false)
shortSlow = FormatFloat(x, 'e', prec, 64)
SetOptimize(true)
if shortSlow != shortFast {
internal/strconv: extract fixed-precision ftoa from ftoaryu.go The fixed-precision ftoa algorithm is not actually documented in the Ryū paper, and it is fairly straightforward: multiply by a power of 10 to get an integer that contains the digits we need. There is also no need for separate float32 and float64 implementations. This CL implements a new fixedFtoa, separate from Ryū. The overall algorithm is the same, but the new code is simpler, faster, and better documented. Now ftoaryu.go is only about shortest-output formatting, so if and when yet another algorithm comes along, it will be clearer what should be replaced (all of ftoaryu.go) and what should not (all of ftoafixed.go). benchmark \ host linux-arm64 local linux-amd64 s7 linux-386 s7:GOARCH=386 vs base vs base vs base vs base vs base vs base AppendFloat/Decimal -0.18% ~ ~ -0.68% +0.49% -0.79% AppendFloat/Float +0.09% ~ +1.50% +0.84% -0.37% -0.69% AppendFloat/Exp -0.51% ~ ~ +1.20% -1.27% -1.01% AppendFloat/NegExp -1.01% ~ +3.43% +1.35% -2.33% ~ AppendFloat/LongExp -1.22% +0.77% ~ ~ -1.48% ~ AppendFloat/Big -2.07% ~ -2.07% -1.97% -2.89% -2.93% AppendFloat/BinaryExp -0.28% +1.06% ~ +1.35% -0.64% -1.64% AppendFloat/32Integer ~ ~ ~ -0.79% ~ -0.66% AppendFloat/32ExactFraction -0.50% ~ +5.69% ~ -1.24% +0.69% AppendFloat/32Point ~ -1.19% +2.59% +1.03% -1.37% +0.80% AppendFloat/32Exp -3.39% -2.79% -8.36% -0.94% -5.72% -5.92% AppendFloat/32NegExp -0.63% ~ ~ +0.98% -1.34% -0.73% AppendFloat/32Shortest -1.00% +1.36% +2.94% ~ ~ ~ AppendFloat/32Fixed8Hard -5.91% -12.45% -6.62% ~ +18.46% +11.61% AppendFloat/32Fixed9Hard -6.53% -11.35% -6.01% -0.97% -18.31% -9.16% AppendFloat/64Fixed1 -13.84% -16.90% -13.13% -10.71% -24.52% -18.94% AppendFloat/64Fixed2 -11.12% -16.97% -12.13% -9.88% -22.73% -15.48% AppendFloat/64Fixed2.5 -21.98% -20.75% -19.08% -14.74% -28.11% -24.92% AppendFloat/64Fixed3 -11.53% -16.21% -10.75% -7.53% -23.11% -15.78% AppendFloat/64Fixed4 -12.89% -12.36% -11.07% -9.79% -14.51% -13.44% AppendFloat/64Fixed5Hard -47.62% -38.59% -40.83% -37.06% -60.51% -55.29% AppendFloat/64Fixed12 -7.40% ~ -8.56% -4.31% -13.82% -8.61% AppendFloat/64Fixed16 -9.10% -8.95% -6.92% -3.92% -12.99% -9.03% AppendFloat/64Fixed12Hard -9.14% -5.24% -6.23% -4.82% -13.58% -8.99% AppendFloat/64Fixed17Hard -6.80% ~ -4.03% -2.84% -19.81% -10.27% AppendFloat/64Fixed18Hard -0.12% ~ ~ ~ ~ ~ AppendFloat/64FixedF1 ~ ~ ~ ~ -0.40% +2.72% AppendFloat/64FixedF2 -0.18% ~ -1.98% -0.95% ~ +1.25% AppendFloat/64FixedF3 -0.29% ~ ~ ~ ~ +1.22% AppendFloat/Slowpath64 -1.16% ~ ~ ~ ~ -2.16% AppendFloat/SlowpathDenormal64 -1.09% ~ ~ -0.88% -0.83% ~ host: linux-arm64 goos: linux goarch: arm64 pkg: internal/strconv cpu: unknown │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-8 60.35n ± 0% 60.24n ± 0% -0.18% (p=0.000 n=20) AppendFloat/Float-8 88.83n ± 0% 88.91n ± 0% +0.09% (p=0.000 n=20) AppendFloat/Exp-8 93.55n ± 0% 93.06n ± 0% -0.51% (p=0.000 n=20) AppendFloat/NegExp-8 94.01n ± 0% 93.06n ± 0% -1.01% (p=0.000 n=20) AppendFloat/LongExp-8 101.00n ± 0% 99.77n ± 0% -1.22% (p=0.000 n=20) AppendFloat/Big-8 106.1n ± 0% 103.9n ± 0% -2.07% (p=0.000 n=20) AppendFloat/BinaryExp-8 47.48n ± 0% 47.35n ± 0% -0.28% (p=0.000 n=20) AppendFloat/32Integer-8 60.45n ± 0% 60.43n ± 0% ~ (p=0.150 n=20) AppendFloat/32ExactFraction-8 86.65n ± 0% 86.22n ± 0% -0.50% (p=0.000 n=20) AppendFloat/32Point-8 83.26n ± 0% 83.21n ± 0% ~ (p=0.046 n=20) AppendFloat/32Exp-8 92.55n ± 0% 89.42n ± 0% -3.39% (p=0.000 n=20) AppendFloat/32NegExp-8 87.89n ± 0% 87.34n ± 0% -0.63% (p=0.000 n=20) AppendFloat/32Shortest-8 77.05n ± 0% 76.28n ± 0% -1.00% (p=0.000 n=20) AppendFloat/32Fixed8Hard-8 55.73n ± 0% 52.44n ± 0% -5.91% (p=0.000 n=20) AppendFloat/32Fixed9Hard-8 64.80n ± 0% 60.57n ± 0% -6.53% (p=0.000 n=20) AppendFloat/64Fixed1-8 53.72n ± 0% 46.29n ± 0% -13.84% (p=0.000 n=20) AppendFloat/64Fixed2-8 52.64n ± 0% 46.79n ± 0% -11.12% (p=0.000 n=20) AppendFloat/64Fixed2.5-8 56.01n ± 0% 43.70n ± 0% -21.98% (p=0.000 n=20) AppendFloat/64Fixed3-8 53.38n ± 0% 47.23n ± 0% -11.53% (p=0.000 n=20) AppendFloat/64Fixed4-8 50.62n ± 0% 44.10n ± 0% -12.89% (p=0.000 n=20) AppendFloat/64Fixed5Hard-8 98.94n ± 0% 51.82n ± 0% -47.62% (p=0.000 n=20) AppendFloat/64Fixed12-8 84.70n ± 0% 78.44n ± 0% -7.40% (p=0.000 n=20) AppendFloat/64Fixed16-8 71.68n ± 0% 65.16n ± 0% -9.10% (p=0.000 n=20) AppendFloat/64Fixed12Hard-8 68.41n ± 0% 62.16n ± 0% -9.14% (p=0.000 n=20) AppendFloat/64Fixed17Hard-8 79.31n ± 0% 73.92n ± 0% -6.80% (p=0.000 n=20) AppendFloat/64Fixed18Hard-8 4.290µ ± 0% 4.285µ ± 0% -0.12% (p=0.000 n=20) AppendFloat/64FixedF1-8 216.0n ± 0% 216.1n ± 0% ~ (p=0.090 n=20) AppendFloat/64FixedF2-8 228.2n ± 0% 227.8n ± 0% -0.18% (p=0.000 n=20) AppendFloat/64FixedF3-8 208.8n ± 0% 208.2n ± 0% -0.29% (p=0.000 n=20) AppendFloat/Slowpath64-8 98.56n ± 0% 97.42n ± 0% -1.16% (p=0.000 n=20) AppendFloat/SlowpathDenormal64-8 95.81n ± 0% 94.77n ± 0% -1.09% (p=0.000 n=20) geomean 93.81n 87.87n -6.33% host: local goos: darwin cpu: Apple M3 Pro │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-12 21.14n ± 0% 21.15n ± 0% ~ (p=0.963 n=20) AppendFloat/Float-12 32.48n ± 1% 32.43n ± 0% ~ (p=0.358 n=20) AppendFloat/Exp-12 31.85n ± 0% 31.94n ± 1% ~ (p=0.634 n=20) AppendFloat/NegExp-12 31.75n ± 0% 32.04n ± 0% ~ (p=0.004 n=20) AppendFloat/LongExp-12 33.55n ± 0% 33.81n ± 0% +0.77% (p=0.000 n=20) AppendFloat/Big-12 35.62n ± 1% 35.73n ± 1% ~ (p=0.888 n=20) AppendFloat/BinaryExp-12 19.26n ± 0% 19.46n ± 1% +1.06% (p=0.000 n=20) AppendFloat/32Integer-12 21.41n ± 0% 21.46n ± 1% ~ (p=0.733 n=20) AppendFloat/32ExactFraction-12 31.23n ± 1% 31.30n ± 1% ~ (p=0.857 n=20) AppendFloat/32Point-12 31.39n ± 1% 31.02n ± 0% -1.19% (p=0.000 n=20) AppendFloat/32Exp-12 32.42n ± 1% 31.52n ± 1% -2.79% (p=0.000 n=20) AppendFloat/32NegExp-12 30.66n ± 1% 30.66n ± 1% ~ (p=0.380 n=20) AppendFloat/32Shortest-12 26.88n ± 1% 27.25n ± 1% +1.36% (p=0.000 n=20) AppendFloat/32Fixed8Hard-12 19.52n ± 0% 17.09n ± 1% -12.45% (p=0.000 n=20) AppendFloat/32Fixed9Hard-12 21.55n ± 2% 19.11n ± 1% -11.35% (p=0.000 n=20) AppendFloat/64Fixed1-12 18.64n ± 0% 15.49n ± 0% -16.90% (p=0.000 n=20) AppendFloat/64Fixed2-12 18.65n ± 0% 15.49n ± 0% -16.97% (p=0.000 n=20) AppendFloat/64Fixed2.5-12 19.23n ± 1% 15.24n ± 0% -20.75% (p=0.000 n=20) AppendFloat/64Fixed3-12 18.61n ± 0% 15.59n ± 1% -16.21% (p=0.000 n=20) AppendFloat/64Fixed4-12 17.55n ± 1% 15.38n ± 0% -12.36% (p=0.000 n=20) AppendFloat/64Fixed5Hard-12 29.27n ± 1% 17.97n ± 0% -38.59% (p=0.000 n=20) AppendFloat/64Fixed12-12 28.26n ± 1% 28.17n ± 10% ~ (p=0.941 n=20) AppendFloat/64Fixed16-12 23.56n ± 0% 21.46n ± 0% -8.95% (p=0.000 n=20) AppendFloat/64Fixed12Hard-12 21.85n ± 2% 20.70n ± 1% -5.24% (p=0.000 n=20) AppendFloat/64Fixed17Hard-12 26.91n ± 1% 27.10n ± 0% ~ (p=0.059 n=20) AppendFloat/64Fixed18Hard-12 2.197µ ± 1% 2.169µ ± 1% ~ (p=0.013 n=20) AppendFloat/64FixedF1-12 103.7n ± 1% 103.3n ± 0% ~ (p=0.035 n=20) AppendFloat/64FixedF2-12 114.8n ± 1% 114.1n ± 1% ~ (p=0.234 n=20) AppendFloat/64FixedF3-12 107.8n ± 1% 107.1n ± 1% ~ (p=0.180 n=20) AppendFloat/Slowpath64-12 32.05n ± 1% 32.00n ± 0% ~ (p=0.952 n=20) AppendFloat/SlowpathDenormal64-12 29.98n ± 1% 30.20n ± 0% ~ (p=0.004 n=20) geomean 33.83n 31.91n -5.68% host: linux-amd64 goos: linux goarch: amd64 cpu: Intel(R) Xeon(R) CPU @ 2.30GHz │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-16 64.00n ± 1% 63.67n ± 1% ~ (p=0.784 n=20) AppendFloat/Float-16 95.99n ± 1% 97.42n ± 1% +1.50% (p=0.000 n=20) AppendFloat/Exp-16 97.59n ± 1% 97.72n ± 1% ~ (p=0.984 n=20) AppendFloat/NegExp-16 97.80n ± 1% 101.15n ± 1% +3.43% (p=0.000 n=20) AppendFloat/LongExp-16 103.1n ± 1% 104.5n ± 1% ~ (p=0.006 n=20) AppendFloat/Big-16 110.8n ± 1% 108.5n ± 1% -2.07% (p=0.000 n=20) AppendFloat/BinaryExp-16 47.82n ± 1% 47.33n ± 1% ~ (p=0.007 n=20) AppendFloat/32Integer-16 63.65n ± 1% 63.51n ± 0% ~ (p=0.560 n=20) AppendFloat/32ExactFraction-16 91.81n ± 1% 97.03n ± 1% +5.69% (p=0.000 n=20) AppendFloat/32Point-16 89.84n ± 1% 92.16n ± 1% +2.59% (p=0.000 n=20) AppendFloat/32Exp-16 103.80n ± 1% 95.12n ± 1% -8.36% (p=0.000 n=20) AppendFloat/32NegExp-16 93.70n ± 1% 94.87n ± 1% ~ (p=0.003 n=20) AppendFloat/32Shortest-16 83.98n ± 1% 86.45n ± 1% +2.94% (p=0.000 n=20) AppendFloat/32Fixed8Hard-16 61.91n ± 1% 57.81n ± 1% -6.62% (p=0.000 n=20) AppendFloat/32Fixed9Hard-16 71.08n ± 0% 66.81n ± 1% -6.01% (p=0.000 n=20) AppendFloat/64Fixed1-16 59.27n ± 2% 51.49n ± 1% -13.13% (p=0.000 n=20) AppendFloat/64Fixed2-16 57.89n ± 1% 50.87n ± 1% -12.13% (p=0.000 n=20) AppendFloat/64Fixed2.5-16 61.04n ± 1% 49.40n ± 1% -19.08% (p=0.000 n=20) AppendFloat/64Fixed3-16 58.42n ± 1% 52.14n ± 1% -10.75% (p=0.000 n=20) AppendFloat/64Fixed4-16 56.52n ± 1% 50.27n ± 1% -11.07% (p=0.000 n=20) AppendFloat/64Fixed5Hard-16 97.79n ± 1% 57.86n ± 1% -40.83% (p=0.000 n=20) AppendFloat/64Fixed12-16 90.78n ± 1% 83.01n ± 1% -8.56% (p=0.000 n=20) AppendFloat/64Fixed16-16 76.11n ± 1% 70.84n ± 0% -6.92% (p=0.000 n=20) AppendFloat/64Fixed12Hard-16 73.56n ± 1% 68.98n ± 2% -6.23% (p=0.000 n=20) AppendFloat/64Fixed17Hard-16 83.20n ± 1% 79.85n ± 1% -4.03% (p=0.000 n=20) AppendFloat/64Fixed18Hard-16 4.947µ ± 1% 4.915µ ± 1% ~ (p=0.229 n=20) AppendFloat/64FixedF1-16 242.4n ± 1% 239.4n ± 1% ~ (p=0.038 n=20) AppendFloat/64FixedF2-16 257.7n ± 2% 252.6n ± 1% -1.98% (p=0.000 n=20) AppendFloat/64FixedF3-16 237.5n ± 0% 237.5n ± 1% ~ (p=0.440 n=20) AppendFloat/Slowpath64-16 99.75n ± 1% 99.78n ± 1% ~ (p=0.995 n=20) AppendFloat/SlowpathDenormal64-16 97.41n ± 1% 98.20n ± 1% ~ (p=0.006 n=20) geomean 100.7n 95.60n -5.05% host: s7 cpu: AMD Ryzen 9 7950X 16-Core Processor │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-32 22.19n ± 0% 22.04n ± 0% -0.68% (p=0.000 n=20) AppendFloat/Float-32 34.59n ± 0% 34.88n ± 0% +0.84% (p=0.000 n=20) AppendFloat/Exp-32 34.47n ± 0% 34.88n ± 0% +1.20% (p=0.000 n=20) AppendFloat/NegExp-32 34.85n ± 0% 35.32n ± 0% +1.35% (p=0.000 n=20) AppendFloat/LongExp-32 37.23n ± 0% 37.09n ± 0% ~ (p=0.003 n=20) AppendFloat/Big-32 39.27n ± 0% 38.50n ± 0% -1.97% (p=0.000 n=20) AppendFloat/BinaryExp-32 17.38n ± 0% 17.61n ± 0% +1.35% (p=0.000 n=20) AppendFloat/32Integer-32 22.26n ± 0% 22.08n ± 0% -0.79% (p=0.000 n=20) AppendFloat/32ExactFraction-32 32.82n ± 0% 32.91n ± 0% ~ (p=0.018 n=20) AppendFloat/32Point-32 32.88n ± 0% 33.22n ± 0% +1.03% (p=0.000 n=20) AppendFloat/32Exp-32 34.95n ± 0% 34.62n ± 0% -0.94% (p=0.000 n=20) AppendFloat/32NegExp-32 33.23n ± 0% 33.55n ± 0% +0.98% (p=0.000 n=20) AppendFloat/32Shortest-32 30.19n ± 0% 30.12n ± 0% ~ (p=0.122 n=20) AppendFloat/32Fixed8Hard-32 22.94n ± 0% 22.88n ± 0% ~ (p=0.124 n=20) AppendFloat/32Fixed9Hard-32 26.20n ± 0% 25.94n ± 1% -0.97% (p=0.000 n=20) AppendFloat/64Fixed1-32 21.10n ± 0% 18.84n ± 0% -10.71% (p=0.000 n=20) AppendFloat/64Fixed2-32 20.75n ± 0% 18.70n ± 0% -9.88% (p=0.000 n=20) AppendFloat/64Fixed2.5-32 21.07n ± 0% 17.96n ± 0% -14.74% (p=0.000 n=20) AppendFloat/64Fixed3-32 21.24n ± 0% 19.64n ± 0% -7.53% (p=0.000 n=20) AppendFloat/64Fixed4-32 20.63n ± 0% 18.61n ± 0% -9.79% (p=0.000 n=20) AppendFloat/64Fixed5Hard-32 34.48n ± 0% 21.70n ± 0% -37.06% (p=0.000 n=20) AppendFloat/64Fixed12-32 32.26n ± 0% 30.87n ± 1% -4.31% (p=0.000 n=20) AppendFloat/64Fixed16-32 27.95n ± 0% 26.86n ± 0% -3.92% (p=0.000 n=20) AppendFloat/64Fixed12Hard-32 27.30n ± 0% 25.98n ± 1% -4.82% (p=0.000 n=20) AppendFloat/64Fixed17Hard-32 30.80n ± 0% 29.93n ± 0% -2.84% (p=0.000 n=20) AppendFloat/64Fixed18Hard-32 1.833µ ± 0% 1.831µ ± 0% ~ (p=0.663 n=20) AppendFloat/64FixedF1-32 83.42n ± 1% 84.00n ± 1% ~ (p=0.003 n=20) AppendFloat/64FixedF2-32 90.10n ± 0% 89.23n ± 1% -0.95% (p=0.001 n=20) AppendFloat/64FixedF3-32 84.42n ± 1% 84.39n ± 0% ~ (p=0.878 n=20) AppendFloat/Slowpath64-32 35.72n ± 0% 35.59n ± 0% ~ (p=0.007 n=20) AppendFloat/SlowpathDenormal64-32 35.36n ± 0% 35.05n ± 0% -0.88% (p=0.000 n=20) geomean 36.05n 34.69n -3.77% host: linux-386 goarch: 386 cpu: Intel(R) Xeon(R) CPU @ 2.30GHz │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-16 132.8n ± 0% 133.5n ± 0% +0.49% (p=0.001 n=20) AppendFloat/Float-16 242.6n ± 0% 241.7n ± 0% -0.37% (p=0.000 n=20) AppendFloat/Exp-16 252.2n ± 0% 249.1n ± 0% -1.27% (p=0.000 n=20) AppendFloat/NegExp-16 253.6n ± 0% 247.7n ± 0% -2.33% (p=0.000 n=20) AppendFloat/LongExp-16 260.9n ± 0% 257.1n ± 0% -1.48% (p=0.000 n=20) AppendFloat/Big-16 293.7n ± 0% 285.2n ± 0% -2.89% (p=0.000 n=20) AppendFloat/BinaryExp-16 89.63n ± 1% 89.06n ± 0% -0.64% (p=0.000 n=20) AppendFloat/32Integer-16 132.6n ± 0% 133.2n ± 0% ~ (p=0.016 n=20) AppendFloat/32ExactFraction-16 216.9n ± 0% 214.2n ± 0% -1.24% (p=0.000 n=20) AppendFloat/32Point-16 205.0n ± 0% 202.2n ± 0% -1.37% (p=0.000 n=20) AppendFloat/32Exp-16 250.2n ± 0% 235.9n ± 0% -5.72% (p=0.000 n=20) AppendFloat/32NegExp-16 213.5n ± 0% 210.6n ± 0% -1.34% (p=0.000 n=20) AppendFloat/32Shortest-16 198.3n ± 0% 197.8n ± 0% ~ (p=0.147 n=20) AppendFloat/32Fixed8Hard-16 114.9n ± 1% 136.0n ± 1% +18.46% (p=0.000 n=20) AppendFloat/32Fixed9Hard-16 189.8n ± 0% 155.0n ± 1% -18.31% (p=0.000 n=20) AppendFloat/64Fixed1-16 175.8n ± 0% 132.7n ± 0% -24.52% (p=0.000 n=20) AppendFloat/64Fixed2-16 166.6n ± 0% 128.7n ± 0% -22.73% (p=0.000 n=20) AppendFloat/64Fixed2.5-16 176.5n ± 0% 126.8n ± 0% -28.11% (p=0.000 n=20) AppendFloat/64Fixed3-16 165.3n ± 0% 127.1n ± 0% -23.11% (p=0.000 n=20) AppendFloat/64Fixed4-16 141.3n ± 0% 120.8n ± 1% -14.51% (p=0.000 n=20) AppendFloat/64Fixed5Hard-16 344.6n ± 0% 136.0n ± 0% -60.51% (p=0.000 n=20) AppendFloat/64Fixed12-16 184.2n ± 0% 158.7n ± 0% -13.82% (p=0.000 n=20) AppendFloat/64Fixed16-16 174.0n ± 0% 151.3n ± 0% -12.99% (p=0.000 n=20) AppendFloat/64Fixed12Hard-16 169.7n ± 0% 146.7n ± 0% -13.58% (p=0.000 n=20) AppendFloat/64Fixed17Hard-16 207.7n ± 0% 166.6n ± 0% -19.81% (p=0.000 n=20) AppendFloat/64Fixed18Hard-16 10.66µ ± 0% 10.63µ ± 0% ~ (p=0.030 n=20) AppendFloat/64FixedF1-16 615.9n ± 0% 613.5n ± 0% -0.40% (p=0.000 n=20) AppendFloat/64FixedF2-16 846.6n ± 0% 847.4n ± 0% ~ (p=0.551 n=20) AppendFloat/64FixedF3-16 609.9n ± 0% 609.5n ± 0% ~ (p=0.213 n=20) AppendFloat/Slowpath64-16 254.1n ± 0% 252.6n ± 1% ~ (p=0.048 n=20) AppendFloat/SlowpathDenormal64-16 251.5n ± 0% 249.4n ± 0% -0.83% (p=0.000 n=20) geomean 249.2n 225.4n -9.54% host: s7:GOARCH=386 cpu: AMD Ryzen 9 7950X 16-Core Processor │ 14b7e09f493 │ f9bf7fcb8e2 │ │ sec/op │ sec/op vs base │ AppendFloat/Decimal-32 42.65n ± 0% 42.31n ± 0% -0.79% (p=0.000 n=20) AppendFloat/Float-32 71.56n ± 0% 71.06n ± 0% -0.69% (p=0.000 n=20) AppendFloat/Exp-32 75.61n ± 1% 74.85n ± 1% -1.01% (p=0.000 n=20) AppendFloat/NegExp-32 74.36n ± 0% 74.30n ± 0% ~ (p=0.482 n=20) AppendFloat/LongExp-32 75.82n ± 0% 75.73n ± 0% ~ (p=0.490 n=20) AppendFloat/Big-32 85.10n ± 0% 82.61n ± 0% -2.93% (p=0.000 n=20) AppendFloat/BinaryExp-32 33.02n ± 0% 32.48n ± 1% -1.64% (p=0.000 n=20) AppendFloat/32Integer-32 41.54n ± 1% 41.27n ± 1% -0.66% (p=0.000 n=20) AppendFloat/32ExactFraction-32 62.48n ± 0% 62.91n ± 0% +0.69% (p=0.000 n=20) AppendFloat/32Point-32 60.17n ± 0% 60.65n ± 0% +0.80% (p=0.000 n=20) AppendFloat/32Exp-32 73.34n ± 0% 68.99n ± 0% -5.92% (p=0.000 n=20) AppendFloat/32NegExp-32 63.29n ± 0% 62.83n ± 0% -0.73% (p=0.000 n=20) AppendFloat/32Shortest-32 58.97n ± 0% 59.07n ± 0% ~ (p=0.029 n=20) AppendFloat/32Fixed8Hard-32 37.42n ± 0% 41.76n ± 1% +11.61% (p=0.000 n=20) AppendFloat/32Fixed9Hard-32 55.18n ± 0% 50.13n ± 1% -9.16% (p=0.000 n=20) AppendFloat/64Fixed1-32 50.89n ± 1% 41.25n ± 0% -18.94% (p=0.000 n=20) AppendFloat/64Fixed2-32 48.33n ± 1% 40.85n ± 1% -15.48% (p=0.000 n=20) AppendFloat/64Fixed2.5-32 52.46n ± 0% 39.39n ± 0% -24.92% (p=0.000 n=20) AppendFloat/64Fixed3-32 48.28n ± 1% 40.66n ± 0% -15.78% (p=0.000 n=20) AppendFloat/64Fixed4-32 44.57n ± 0% 38.58n ± 0% -13.44% (p=0.000 n=20) AppendFloat/64Fixed5Hard-32 96.16n ± 0% 42.99n ± 1% -55.29% (p=0.000 n=20) AppendFloat/64Fixed12-32 56.84n ± 0% 51.95n ± 1% -8.61% (p=0.000 n=20) AppendFloat/64Fixed16-32 54.23n ± 0% 49.33n ± 0% -9.03% (p=0.000 n=20) AppendFloat/64Fixed12Hard-32 53.47n ± 0% 48.67n ± 0% -8.99% (p=0.000 n=20) AppendFloat/64Fixed17Hard-32 61.76n ± 0% 55.42n ± 1% -10.27% (p=0.000 n=20) AppendFloat/64Fixed18Hard-32 3.998µ ± 1% 4.001µ ± 0% ~ (p=0.449 n=20) AppendFloat/64FixedF1-32 161.8n ± 0% 166.2n ± 1% +2.72% (p=0.000 n=20) AppendFloat/64FixedF2-32 223.4n ± 2% 226.2n ± 1% +1.25% (p=0.000 n=20) AppendFloat/64FixedF3-32 159.6n ± 0% 161.6n ± 1% +1.22% (p=0.000 n=20) AppendFloat/Slowpath64-32 76.69n ± 0% 75.03n ± 0% -2.16% (p=0.000 n=20) AppendFloat/SlowpathDenormal64-32 75.02n ± 0% 74.36n ± 1% ~ (p=0.003 n=20) geomean 74.66n 69.39n -7.06% Change-Id: I9db46471a93bd2aab3c2796e563d154cb531d4cb Reviewed-on: https://go-review.googlesource.com/c/go/+/717182 Reviewed-by: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Russ Cox <rsc@golang.org>
2025-11-01 09:41:40 -04:00
t.Errorf("%b printed with %%.%de as %s, want %s", x, prec, shortFast, shortSlow)
}
}
}
func TestFormatFloatInvalidBitSize(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Fatalf("expected panic due to invalid bitSize")
}
}()
_ = FormatFloat(3.14, 'g', -1, 100)
}
var ftoaBenches = []struct {
name string
float float64
fmt byte
prec int
bitSize int
}{
{"Decimal", 33909, 'g', -1, 64},
{"Float", 339.7784, 'g', -1, 64},
{"Exp", -5.09e75, 'g', -1, 64},
{"NegExp", -5.11e-95, 'g', -1, 64},
strconv: Implement Ryū algorithm for ftoa shortest mode This patch implements the algorithm from Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369) for formatting floating-point numbers with a fixed number of decimal digits. It is not a direct translation of the reference C implementation but still follows the original paper. In particular, it uses full 128-bit powers of 10, which allows for more precision in the other modes (fixed ftoa, atof). name old time/op new time/op delta AppendFloat/Decimal-4 49.6ns ± 3% 59.3ns ± 0% +19.59% (p=0.008 n=5+5) AppendFloat/Float-4 122ns ± 1% 91ns ± 1% -25.92% (p=0.008 n=5+5) AppendFloat/Exp-4 89.3ns ± 1% 100.0ns ± 1% +11.98% (p=0.008 n=5+5) AppendFloat/NegExp-4 88.3ns ± 2% 97.1ns ± 1% +9.87% (p=0.008 n=5+5) AppendFloat/LongExp-4 143ns ± 2% 103ns ± 0% -28.17% (p=0.016 n=5+4) AppendFloat/Big-4 144ns ± 1% 110ns ± 1% -23.26% (p=0.008 n=5+5) AppendFloat/BinaryExp-4 46.2ns ± 2% 46.0ns ± 1% ~ (p=0.603 n=5+5) AppendFloat/32Integer-4 49.1ns ± 1% 58.7ns ± 1% +19.57% (p=0.008 n=5+5) AppendFloat/32ExactFraction-4 95.6ns ± 1% 88.6ns ± 1% -7.30% (p=0.008 n=5+5) AppendFloat/32Point-4 122ns ± 1% 87ns ± 1% -28.63% (p=0.008 n=5+5) AppendFloat/32Exp-4 88.6ns ± 2% 95.0ns ± 1% +7.29% (p=0.008 n=5+5) AppendFloat/32NegExp-4 87.2ns ± 1% 91.3ns ± 1% +4.63% (p=0.008 n=5+5) AppendFloat/32Shortest-4 107ns ± 1% 82ns ± 0% -24.08% (p=0.008 n=5+5) AppendFloat/Slowpath64-4 1.00µs ± 1% 0.10µs ± 0% -89.92% (p=0.016 n=5+4) AppendFloat/SlowpathDenormal64-4 34.1µs ± 3% 0.1µs ± 1% -99.72% (p=0.008 n=5+5) Fixes #15672 Change-Id: Ib90dfa245f62490a6666671896013cf3f9a1fb22 Reviewed-on: https://go-review.googlesource.com/c/go/+/170080 Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Nigel Tao <nigeltao@golang.org> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Nigel Tao <nigeltao@golang.org>
2019-03-27 06:55:52 +01:00
{"LongExp", 1.234567890123456e-78, 'g', -1, 64},
{"Big", 123456789123456789123456789, 'g', -1, 64},
{"BinaryExp", -1, 'b', -1, 64},
{"32Integer", 33909, 'g', -1, 32},
{"32ExactFraction", 3.375, 'g', -1, 32},
{"32Point", 339.7784, 'g', -1, 32},
{"32Exp", -5.09e25, 'g', -1, 32},
{"32NegExp", -5.11e-25, 'g', -1, 32},
strconv: Implement Ryū algorithm for ftoa shortest mode This patch implements the algorithm from Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369) for formatting floating-point numbers with a fixed number of decimal digits. It is not a direct translation of the reference C implementation but still follows the original paper. In particular, it uses full 128-bit powers of 10, which allows for more precision in the other modes (fixed ftoa, atof). name old time/op new time/op delta AppendFloat/Decimal-4 49.6ns ± 3% 59.3ns ± 0% +19.59% (p=0.008 n=5+5) AppendFloat/Float-4 122ns ± 1% 91ns ± 1% -25.92% (p=0.008 n=5+5) AppendFloat/Exp-4 89.3ns ± 1% 100.0ns ± 1% +11.98% (p=0.008 n=5+5) AppendFloat/NegExp-4 88.3ns ± 2% 97.1ns ± 1% +9.87% (p=0.008 n=5+5) AppendFloat/LongExp-4 143ns ± 2% 103ns ± 0% -28.17% (p=0.016 n=5+4) AppendFloat/Big-4 144ns ± 1% 110ns ± 1% -23.26% (p=0.008 n=5+5) AppendFloat/BinaryExp-4 46.2ns ± 2% 46.0ns ± 1% ~ (p=0.603 n=5+5) AppendFloat/32Integer-4 49.1ns ± 1% 58.7ns ± 1% +19.57% (p=0.008 n=5+5) AppendFloat/32ExactFraction-4 95.6ns ± 1% 88.6ns ± 1% -7.30% (p=0.008 n=5+5) AppendFloat/32Point-4 122ns ± 1% 87ns ± 1% -28.63% (p=0.008 n=5+5) AppendFloat/32Exp-4 88.6ns ± 2% 95.0ns ± 1% +7.29% (p=0.008 n=5+5) AppendFloat/32NegExp-4 87.2ns ± 1% 91.3ns ± 1% +4.63% (p=0.008 n=5+5) AppendFloat/32Shortest-4 107ns ± 1% 82ns ± 0% -24.08% (p=0.008 n=5+5) AppendFloat/Slowpath64-4 1.00µs ± 1% 0.10µs ± 0% -89.92% (p=0.016 n=5+4) AppendFloat/SlowpathDenormal64-4 34.1µs ± 3% 0.1µs ± 1% -99.72% (p=0.008 n=5+5) Fixes #15672 Change-Id: Ib90dfa245f62490a6666671896013cf3f9a1fb22 Reviewed-on: https://go-review.googlesource.com/c/go/+/170080 Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Nigel Tao <nigeltao@golang.org> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Nigel Tao <nigeltao@golang.org>
2019-03-27 06:55:52 +01:00
{"32Shortest", 1.234567e-8, 'g', -1, 32},
strconv: implement Ryū-like algorithm for fixed precision ftoa This patch implements a simplified version of Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369) for formatting floating-point numbers with a fixed number of decimal digits. It uses the same principles but does not need to handle the complex task of finding a shortest representation. This allows to handle a few more cases than Grisu3, notably formatting with up to 18 significant digits. name old time/op new time/op delta AppendFloat/32Fixed8Hard-4 72.0ns ± 2% 56.0ns ± 2% -22.28% (p=0.000 n=10+10) AppendFloat/32Fixed9Hard-4 74.8ns ± 0% 64.2ns ± 2% -14.16% (p=0.000 n=8+10) AppendFloat/64Fixed1-4 60.4ns ± 1% 54.2ns ± 1% -10.31% (p=0.000 n=10+9) AppendFloat/64Fixed2-4 66.3ns ± 1% 53.3ns ± 1% -19.54% (p=0.000 n=10+9) AppendFloat/64Fixed3-4 61.0ns ± 1% 55.0ns ± 2% -9.80% (p=0.000 n=9+10) AppendFloat/64Fixed4-4 66.9ns ± 0% 52.0ns ± 2% -22.20% (p=0.000 n=8+10) AppendFloat/64Fixed12-4 95.5ns ± 1% 76.2ns ± 3% -20.19% (p=0.000 n=10+9) AppendFloat/64Fixed16-4 1.62µs ± 0% 0.07µs ± 2% -95.69% (p=0.000 n=10+10) AppendFloat/64Fixed12Hard-4 1.27µs ± 1% 0.07µs ± 1% -94.83% (p=0.000 n=9+9) AppendFloat/64Fixed17Hard-4 3.68µs ± 1% 0.08µs ± 2% -97.86% (p=0.000 n=10+9) AppendFloat/64Fixed18Hard-4 3.67µs ± 0% 3.72µs ± 1% +1.44% (p=0.000 n=9+10) Updates #15672 Change-Id: I160963e141dd48287ad8cf57bcc3c686277788e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/170079 Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Nigel Tao <nigeltao@golang.org> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org>
2019-03-24 23:21:38 +01:00
{"32Fixed8Hard", math.Ldexp(15961084, -125), 'e', 8, 32},
{"32Fixed9Hard", math.Ldexp(14855922, -83), 'e', 9, 32},
{"64Fixed1", 123456, 'e', 3, 64},
{"64Fixed2", 123.456, 'e', 3, 64},
{"64Fixed2.5", 1.2345e+06, 'e', 3, 64},
{"64Fixed3", 1.23456e+78, 'e', 3, 64},
{"64Fixed4", 1.23456e-78, 'e', 3, 64},
{"64Fixed5Hard", 4.096e+25, 'e', 5, 64}, // needs divisiblePow5(..., 20)
strconv: implement Ryū-like algorithm for fixed precision ftoa This patch implements a simplified version of Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369) for formatting floating-point numbers with a fixed number of decimal digits. It uses the same principles but does not need to handle the complex task of finding a shortest representation. This allows to handle a few more cases than Grisu3, notably formatting with up to 18 significant digits. name old time/op new time/op delta AppendFloat/32Fixed8Hard-4 72.0ns ± 2% 56.0ns ± 2% -22.28% (p=0.000 n=10+10) AppendFloat/32Fixed9Hard-4 74.8ns ± 0% 64.2ns ± 2% -14.16% (p=0.000 n=8+10) AppendFloat/64Fixed1-4 60.4ns ± 1% 54.2ns ± 1% -10.31% (p=0.000 n=10+9) AppendFloat/64Fixed2-4 66.3ns ± 1% 53.3ns ± 1% -19.54% (p=0.000 n=10+9) AppendFloat/64Fixed3-4 61.0ns ± 1% 55.0ns ± 2% -9.80% (p=0.000 n=9+10) AppendFloat/64Fixed4-4 66.9ns ± 0% 52.0ns ± 2% -22.20% (p=0.000 n=8+10) AppendFloat/64Fixed12-4 95.5ns ± 1% 76.2ns ± 3% -20.19% (p=0.000 n=10+9) AppendFloat/64Fixed16-4 1.62µs ± 0% 0.07µs ± 2% -95.69% (p=0.000 n=10+10) AppendFloat/64Fixed12Hard-4 1.27µs ± 1% 0.07µs ± 1% -94.83% (p=0.000 n=9+9) AppendFloat/64Fixed17Hard-4 3.68µs ± 1% 0.08µs ± 2% -97.86% (p=0.000 n=10+9) AppendFloat/64Fixed18Hard-4 3.67µs ± 0% 3.72µs ± 1% +1.44% (p=0.000 n=9+10) Updates #15672 Change-Id: I160963e141dd48287ad8cf57bcc3c686277788e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/170079 Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Nigel Tao <nigeltao@golang.org> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org>
2019-03-24 23:21:38 +01:00
{"64Fixed12", 1.23456e-78, 'e', 12, 64},
{"64Fixed16", 1.23456e-78, 'e', 16, 64},
// From testdata/testfp.txt
{"64Fixed12Hard", math.Ldexp(6965949469487146, -249), 'e', 12, 64},
{"64Fixed17Hard", math.Ldexp(8887055249355788, 665), 'e', 17, 64},
{"64Fixed18Hard", math.Ldexp(6994187472632449, 690), 'e', 18, 64},
{"64FixedF1", 123.456, 'f', 6, 64},
{"64FixedF2", 0.0123, 'f', 6, 64},
{"64FixedF3", 12.3456, 'f', 2, 64},
// Trigger slow path (see issue #15672).
strconv: Implement Ryū algorithm for ftoa shortest mode This patch implements the algorithm from Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369) for formatting floating-point numbers with a fixed number of decimal digits. It is not a direct translation of the reference C implementation but still follows the original paper. In particular, it uses full 128-bit powers of 10, which allows for more precision in the other modes (fixed ftoa, atof). name old time/op new time/op delta AppendFloat/Decimal-4 49.6ns ± 3% 59.3ns ± 0% +19.59% (p=0.008 n=5+5) AppendFloat/Float-4 122ns ± 1% 91ns ± 1% -25.92% (p=0.008 n=5+5) AppendFloat/Exp-4 89.3ns ± 1% 100.0ns ± 1% +11.98% (p=0.008 n=5+5) AppendFloat/NegExp-4 88.3ns ± 2% 97.1ns ± 1% +9.87% (p=0.008 n=5+5) AppendFloat/LongExp-4 143ns ± 2% 103ns ± 0% -28.17% (p=0.016 n=5+4) AppendFloat/Big-4 144ns ± 1% 110ns ± 1% -23.26% (p=0.008 n=5+5) AppendFloat/BinaryExp-4 46.2ns ± 2% 46.0ns ± 1% ~ (p=0.603 n=5+5) AppendFloat/32Integer-4 49.1ns ± 1% 58.7ns ± 1% +19.57% (p=0.008 n=5+5) AppendFloat/32ExactFraction-4 95.6ns ± 1% 88.6ns ± 1% -7.30% (p=0.008 n=5+5) AppendFloat/32Point-4 122ns ± 1% 87ns ± 1% -28.63% (p=0.008 n=5+5) AppendFloat/32Exp-4 88.6ns ± 2% 95.0ns ± 1% +7.29% (p=0.008 n=5+5) AppendFloat/32NegExp-4 87.2ns ± 1% 91.3ns ± 1% +4.63% (p=0.008 n=5+5) AppendFloat/32Shortest-4 107ns ± 1% 82ns ± 0% -24.08% (p=0.008 n=5+5) AppendFloat/Slowpath64-4 1.00µs ± 1% 0.10µs ± 0% -89.92% (p=0.016 n=5+4) AppendFloat/SlowpathDenormal64-4 34.1µs ± 3% 0.1µs ± 1% -99.72% (p=0.008 n=5+5) Fixes #15672 Change-Id: Ib90dfa245f62490a6666671896013cf3f9a1fb22 Reviewed-on: https://go-review.googlesource.com/c/go/+/170080 Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Nigel Tao <nigeltao@golang.org> Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Nigel Tao <nigeltao@golang.org>
2019-03-27 06:55:52 +01:00
// The shortest is: 8.034137530808823e+43
{"Slowpath64", 8.03413753080882349e+43, 'e', -1, 64},
// This denormal is pathological because the lower/upper
// halfways to neighboring floats are:
// 622666234635.321003e-320 ~= 622666234635.321e-320
// 622666234635.321497e-320 ~= 622666234635.3215e-320
// making it hard to find the 3rd digit
{"SlowpathDenormal64", 622666234635.3213e-320, 'e', -1, 64},
}
func BenchmarkFormatFloat(b *testing.B) {
for _, c := range ftoaBenches {
b.Run(c.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
FormatFloat(c.float, c.fmt, c.prec, c.bitSize)
}
})
}
}
func BenchmarkAppendFloat(b *testing.B) {
dst := make([]byte, 30)
for _, c := range ftoaBenches {
b.Run(c.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
AppendFloat(dst[:0], c.float, c.fmt, c.prec, c.bitSize)
}
})
}
}