aboutsummaryrefslogtreecommitdiff
path: root/src/strconv
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2025-10-28 21:41:40 -0400
committerRuss Cox <rsc@golang.org>2025-10-29 11:00:02 -0700
commitb2a346bbd1e1e9cb069001cf86ef39b0dd5722f8 (patch)
tree7711a7ec61ce7e8b9587a0a6daf6f4c61f21e57f /src/strconv
parent041f564b3e6fa3f4af13a01b94db14c1ee8a42e0 (diff)
downloadgo-b2a346bbd1e1e9cb069001cf86ef39b0dd5722f8.tar.xz
strconv: move all but Quote to internal/strconv
This will let low-level things depend on the canonical routines, even for floating-point printing. Change-Id: I31207dc6584ad90d4e365dbe6eaf20f8662ed22d Reviewed-on: https://go-review.googlesource.com/c/go/+/716000 Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/strconv')
-rw-r--r--src/strconv/atob.go35
-rw-r--r--src/strconv/atob_test.go91
-rw-r--r--src/strconv/atoc.go107
-rw-r--r--src/strconv/atoc_test.go229
-rw-r--r--src/strconv/atof.go708
-rw-r--r--src/strconv/atof_test.go754
-rw-r--r--src/strconv/atoi.go328
-rw-r--r--src/strconv/atoi_test.go677
-rw-r--r--src/strconv/ctoa.go27
-rw-r--r--src/strconv/ctoa_test.go53
-rw-r--r--src/strconv/decimal.go415
-rw-r--r--src/strconv/decimal_test.go127
-rw-r--r--src/strconv/eisel_lemire.go167
-rw-r--r--src/strconv/export_test.go24
-rw-r--r--src/strconv/fp_test.go138
-rw-r--r--src/strconv/ftoa.go582
-rw-r--r--src/strconv/ftoa_test.go336
-rw-r--r--src/strconv/ftoaryu.go524
-rw-r--r--src/strconv/import_test.go12
-rw-r--r--src/strconv/itoa.go308
-rw-r--r--src/strconv/itoa_test.go244
-rw-r--r--src/strconv/math.go57
-rw-r--r--src/strconv/math_test.go80
-rw-r--r--src/strconv/number.go286
-rw-r--r--src/strconv/number_test.go956
-rw-r--r--src/strconv/pow10gen.go91
-rw-r--r--src/strconv/pow10tab.go715
-rw-r--r--src/strconv/testdata/testfp.txt181
28 files changed, 1246 insertions, 7006 deletions
diff --git a/src/strconv/atob.go b/src/strconv/atob.go
deleted file mode 100644
index 0a495008d7..0000000000
--- a/src/strconv/atob.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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
-
-// ParseBool returns the boolean value represented by the string.
-// It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.
-// Any other value returns an error.
-func ParseBool(str string) (bool, error) {
- switch str {
- case "1", "t", "T", "true", "TRUE", "True":
- return true, nil
- case "0", "f", "F", "false", "FALSE", "False":
- return false, nil
- }
- return false, syntaxError("ParseBool", str)
-}
-
-// FormatBool returns "true" or "false" according to the value of b.
-func FormatBool(b bool) string {
- if b {
- return "true"
- }
- return "false"
-}
-
-// AppendBool appends "true" or "false", according to the value of b,
-// to dst and returns the extended buffer.
-func AppendBool(dst []byte, b bool) []byte {
- if b {
- return append(dst, "true"...)
- }
- return append(dst, "false"...)
-}
diff --git a/src/strconv/atob_test.go b/src/strconv/atob_test.go
deleted file mode 100644
index 40d43a9f8f..0000000000
--- a/src/strconv/atob_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// 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 (
- "bytes"
- . "strconv"
- "testing"
-)
-
-type atobTest struct {
- in string
- out bool
- err error
-}
-
-var atobtests = []atobTest{
- {"", false, ErrSyntax},
- {"asdf", false, ErrSyntax},
- {"0", false, nil},
- {"f", false, nil},
- {"F", false, nil},
- {"FALSE", false, nil},
- {"false", false, nil},
- {"False", false, nil},
- {"1", true, nil},
- {"t", true, nil},
- {"T", true, nil},
- {"TRUE", true, nil},
- {"true", true, nil},
- {"True", true, nil},
-}
-
-func TestParseBool(t *testing.T) {
- for _, test := range atobtests {
- b, e := ParseBool(test.in)
- if test.err != nil {
- // expect an error
- if e == nil {
- t.Errorf("ParseBool(%s) = nil; want %s", test.in, test.err)
- } else {
- // NumError assertion must succeed; it's the only thing we return.
- if e.(*NumError).Err != test.err {
- t.Errorf("ParseBool(%s) = %s; want %s", test.in, e, test.err)
- }
- }
- } else {
- if e != nil {
- t.Errorf("ParseBool(%s) = %s; want nil", test.in, e)
- }
- if b != test.out {
- t.Errorf("ParseBool(%s) = %t; want %t", test.in, b, test.out)
- }
- }
- }
-}
-
-var boolString = map[bool]string{
- true: "true",
- false: "false",
-}
-
-func TestFormatBool(t *testing.T) {
- for b, s := range boolString {
- if f := FormatBool(b); f != s {
- t.Errorf("FormatBool(%v) = %q; want %q", b, f, s)
- }
- }
-}
-
-type appendBoolTest struct {
- b bool
- in []byte
- out []byte
-}
-
-var appendBoolTests = []appendBoolTest{
- {true, []byte("foo "), []byte("foo true")},
- {false, []byte("foo "), []byte("foo false")},
-}
-
-func TestAppendBool(t *testing.T) {
- for _, test := range appendBoolTests {
- b := AppendBool(test.in, test.b)
- if !bytes.Equal(b, test.out) {
- t.Errorf("AppendBool(%q, %v) = %q; want %q", test.in, test.b, b, test.out)
- }
- }
-}
diff --git a/src/strconv/atoc.go b/src/strconv/atoc.go
deleted file mode 100644
index 560bd7920d..0000000000
--- a/src/strconv/atoc.go
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2020 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
-
-import "internal/stringslite"
-
-const fnParseComplex = "ParseComplex"
-
-// convErr splits an error returned by parseFloatPrefix
-// into a syntax or range error for ParseComplex.
-func convErr(err error, s string) (syntax, range_ error) {
- if x, ok := err.(*NumError); ok {
- x.Func = fnParseComplex
- x.Num = stringslite.Clone(s)
- if x.Err == ErrRange {
- return nil, x
- }
- }
- return err, nil
-}
-
-// ParseComplex converts the string s to a complex number
-// with the precision specified by bitSize: 64 for complex64, or 128 for complex128.
-// When bitSize=64, the result still has type complex128, but it will be
-// convertible to complex64 without changing its value.
-//
-// The number represented by s must be of the form N, Ni, or N±Ni, where N stands
-// for a floating-point number as recognized by [ParseFloat], and i is the imaginary
-// component. If the second N is unsigned, a + sign is required between the two components
-// as indicated by the ±. If the second N is NaN, only a + sign is accepted.
-// The form may be parenthesized and cannot contain any spaces.
-// The resulting complex number consists of the two components converted by ParseFloat.
-//
-// The errors that ParseComplex returns have concrete type [*NumError]
-// and include err.Num = s.
-//
-// If s is not syntactically well-formed, ParseComplex returns err.Err = ErrSyntax.
-//
-// If s is syntactically well-formed but either component is more than 1/2 ULP
-// away from the largest floating point number of the given component's size,
-// ParseComplex returns err.Err = ErrRange and c = ±Inf for the respective component.
-func ParseComplex(s string, bitSize int) (complex128, error) {
- size := 64
- if bitSize == 64 {
- size = 32 // complex64 uses float32 parts
- }
-
- orig := s
-
- // Remove parentheses, if any.
- if len(s) >= 2 && s[0] == '(' && s[len(s)-1] == ')' {
- s = s[1 : len(s)-1]
- }
-
- var pending error // pending range error, or nil
-
- // Read real part (possibly imaginary part if followed by 'i').
- re, n, err := parseFloatPrefix(s, size)
- if err != nil {
- err, pending = convErr(err, orig)
- if err != nil {
- return 0, err
- }
- }
- s = s[n:]
-
- // If we have nothing left, we're done.
- if len(s) == 0 {
- return complex(re, 0), pending
- }
-
- // Otherwise, look at the next character.
- switch s[0] {
- case '+':
- // Consume the '+' to avoid an error if we have "+NaNi", but
- // do this only if we don't have a "++" (don't hide that error).
- if len(s) > 1 && s[1] != '+' {
- s = s[1:]
- }
- case '-':
- // ok
- case 'i':
- // If 'i' is the last character, we only have an imaginary part.
- if len(s) == 1 {
- return complex(0, re), pending
- }
- fallthrough
- default:
- return 0, syntaxError(fnParseComplex, orig)
- }
-
- // Read imaginary part.
- im, n, err := parseFloatPrefix(s, size)
- if err != nil {
- err, pending = convErr(err, orig)
- if err != nil {
- return 0, err
- }
- }
- s = s[n:]
- if s != "i" {
- return 0, syntaxError(fnParseComplex, orig)
- }
- return complex(re, im), pending
-}
diff --git a/src/strconv/atoc_test.go b/src/strconv/atoc_test.go
deleted file mode 100644
index 4c1aad0900..0000000000
--- a/src/strconv/atoc_test.go
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright 2020 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 (
- "math"
- "math/cmplx"
- "reflect"
- . "strconv"
- "testing"
-)
-
-var (
- infp0 = complex(math.Inf(+1), 0)
- infm0 = complex(math.Inf(-1), 0)
- inf0p = complex(0, math.Inf(+1))
- inf0m = complex(0, math.Inf(-1))
-
- infpp = complex(math.Inf(+1), math.Inf(+1))
- infpm = complex(math.Inf(+1), math.Inf(-1))
- infmp = complex(math.Inf(-1), math.Inf(+1))
- infmm = complex(math.Inf(-1), math.Inf(-1))
-)
-
-type atocTest struct {
- in string
- out complex128
- err error
-}
-
-func TestParseComplex(t *testing.T) {
- tests := []atocTest{
- // Clearly invalid
- {"", 0, ErrSyntax},
- {" ", 0, ErrSyntax},
- {"(", 0, ErrSyntax},
- {")", 0, ErrSyntax},
- {"i", 0, ErrSyntax},
- {"+i", 0, ErrSyntax},
- {"-i", 0, ErrSyntax},
- {"1I", 0, ErrSyntax},
- {"10 + 5i", 0, ErrSyntax},
- {"3+", 0, ErrSyntax},
- {"3+5", 0, ErrSyntax},
- {"3+5+5i", 0, ErrSyntax},
-
- // Parentheses
- {"()", 0, ErrSyntax},
- {"(i)", 0, ErrSyntax},
- {"(0)", 0, nil},
- {"(1i)", 1i, nil},
- {"(3.0+5.5i)", 3.0 + 5.5i, nil},
- {"(1)+1i", 0, ErrSyntax},
- {"(3.0+5.5i", 0, ErrSyntax},
- {"3.0+5.5i)", 0, ErrSyntax},
-
- // NaNs
- {"NaN", complex(math.NaN(), 0), nil},
- {"NANi", complex(0, math.NaN()), nil},
- {"nan+nAni", complex(math.NaN(), math.NaN()), nil},
- {"+NaN", 0, ErrSyntax},
- {"-NaN", 0, ErrSyntax},
- {"NaN-NaNi", 0, ErrSyntax},
-
- // Infs
- {"Inf", infp0, nil},
- {"+inf", infp0, nil},
- {"-inf", infm0, nil},
- {"Infinity", infp0, nil},
- {"+INFINITY", infp0, nil},
- {"-infinity", infm0, nil},
- {"+infi", inf0p, nil},
- {"0-infinityi", inf0m, nil},
- {"Inf+Infi", infpp, nil},
- {"+Inf-Infi", infpm, nil},
- {"-Infinity+Infi", infmp, nil},
- {"inf-inf", 0, ErrSyntax},
-
- // Zeros
- {"0", 0, nil},
- {"0i", 0, nil},
- {"-0.0i", 0, nil},
- {"0+0.0i", 0, nil},
- {"0e+0i", 0, nil},
- {"0e-0+0i", 0, nil},
- {"-0.0-0.0i", 0, nil},
- {"0e+012345", 0, nil},
- {"0x0p+012345i", 0, nil},
- {"0x0.00p-012345i", 0, nil},
- {"+0e-0+0e-0i", 0, nil},
- {"0e+0+0e+0i", 0, nil},
- {"-0e+0-0e+0i", 0, nil},
-
- // Regular non-zeroes
- {"0.1", 0.1, nil},
- {"0.1i", 0 + 0.1i, nil},
- {"0.123", 0.123, nil},
- {"0.123i", 0 + 0.123i, nil},
- {"0.123+0.123i", 0.123 + 0.123i, nil},
- {"99", 99, nil},
- {"+99", 99, nil},
- {"-99", -99, nil},
- {"+1i", 1i, nil},
- {"-1i", -1i, nil},
- {"+3+1i", 3 + 1i, nil},
- {"30+3i", 30 + 3i, nil},
- {"+3e+3-3e+3i", 3e+3 - 3e+3i, nil},
- {"+3e+3+3e+3i", 3e+3 + 3e+3i, nil},
- {"+3e+3+3e+3i+", 0, ErrSyntax},
-
- // Separators
- {"0.1", 0.1, nil},
- {"0.1i", 0 + 0.1i, nil},
- {"0.1_2_3", 0.123, nil},
- {"+0x_3p3i", 0x3p3i, nil},
- {"0_0+0x_0p0i", 0, nil},
- {"0x_10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
- {"+0x_1_0.3p-8+0x_3_0p3i", 0x10.3p-8 + 0x30p3i, nil},
- {"0x1_0.3p+8-0x_3p3i", 0x10.3p+8 - 0x3p3i, nil},
-
- // Hexadecimals
- {"0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
- {"+0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
- {"0x10.3p+8-0x3p3i", 0x10.3p+8 - 0x3p3i, nil},
- {"0x1p0", 1, nil},
- {"0x1p1", 2, nil},
- {"0x1p-1", 0.5, nil},
- {"0x1ep-1", 15, nil},
- {"-0x1ep-1", -15, nil},
- {"-0x2p3", -16, nil},
- {"0x1e2", 0, ErrSyntax},
- {"1p2", 0, ErrSyntax},
- {"0x1e2i", 0, ErrSyntax},
-
- // ErrRange
- // next float64 - too large
- {"+0x1p1024", infp0, ErrRange},
- {"-0x1p1024", infm0, ErrRange},
- {"+0x1p1024i", inf0p, ErrRange},
- {"-0x1p1024i", inf0m, ErrRange},
- {"+0x1p1024+0x1p1024i", infpp, ErrRange},
- {"+0x1p1024-0x1p1024i", infpm, ErrRange},
- {"-0x1p1024+0x1p1024i", infmp, ErrRange},
- {"-0x1p1024-0x1p1024i", infmm, ErrRange},
- // the border is ...158079
- // borderline - okay
- {"+0x1.fffffffffffff7fffp1023+0x1.fffffffffffff7fffp1023i", 1.7976931348623157e+308 + 1.7976931348623157e+308i, nil},
- {"+0x1.fffffffffffff7fffp1023-0x1.fffffffffffff7fffp1023i", 1.7976931348623157e+308 - 1.7976931348623157e+308i, nil},
- {"-0x1.fffffffffffff7fffp1023+0x1.fffffffffffff7fffp1023i", -1.7976931348623157e+308 + 1.7976931348623157e+308i, nil},
- {"-0x1.fffffffffffff7fffp1023-0x1.fffffffffffff7fffp1023i", -1.7976931348623157e+308 - 1.7976931348623157e+308i, nil},
- // borderline - too large
- {"+0x1.fffffffffffff8p1023", infp0, ErrRange},
- {"-0x1fffffffffffff.8p+971", infm0, ErrRange},
- {"+0x1.fffffffffffff8p1023i", inf0p, ErrRange},
- {"-0x1fffffffffffff.8p+971i", inf0m, ErrRange},
- {"+0x1.fffffffffffff8p1023+0x1.fffffffffffff8p1023i", infpp, ErrRange},
- {"+0x1.fffffffffffff8p1023-0x1.fffffffffffff8p1023i", infpm, ErrRange},
- {"-0x1fffffffffffff.8p+971+0x1fffffffffffff.8p+971i", infmp, ErrRange},
- {"-0x1fffffffffffff8p+967-0x1fffffffffffff8p+967i", infmm, ErrRange},
- // a little too large
- {"1e308+1e308i", 1e+308 + 1e+308i, nil},
- {"2e308+2e308i", infpp, ErrRange},
- {"1e309+1e309i", infpp, ErrRange},
- {"0x1p1025+0x1p1025i", infpp, ErrRange},
- {"2e308", infp0, ErrRange},
- {"1e309", infp0, ErrRange},
- {"0x1p1025", infp0, ErrRange},
- {"2e308i", inf0p, ErrRange},
- {"1e309i", inf0p, ErrRange},
- {"0x1p1025i", inf0p, ErrRange},
- // way too large
- {"+1e310+1e310i", infpp, ErrRange},
- {"+1e310-1e310i", infpm, ErrRange},
- {"-1e310+1e310i", infmp, ErrRange},
- {"-1e310-1e310i", infmm, ErrRange},
- // under/overflow exponent
- {"1e-4294967296", 0, nil},
- {"1e-4294967296i", 0, nil},
- {"1e-4294967296+1i", 1i, nil},
- {"1+1e-4294967296i", 1, nil},
- {"1e-4294967296+1e-4294967296i", 0, nil},
- {"1e+4294967296", infp0, ErrRange},
- {"1e+4294967296i", inf0p, ErrRange},
- {"1e+4294967296+1e+4294967296i", infpp, ErrRange},
- {"1e+4294967296-1e+4294967296i", infpm, ErrRange},
- }
- for i := range tests {
- test := &tests[i]
- if test.err != nil {
- test.err = &NumError{Func: "ParseComplex", Num: test.in, Err: test.err}
- }
- got, err := ParseComplex(test.in, 128)
- if !reflect.DeepEqual(err, test.err) {
- t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
- }
- if !(cmplx.IsNaN(test.out) && cmplx.IsNaN(got)) && got != test.out {
- t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
- }
-
- if complex128(complex64(test.out)) == test.out {
- got, err := ParseComplex(test.in, 64)
- if !reflect.DeepEqual(err, test.err) {
- t.Fatalf("ParseComplex(%q, 64) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
- }
- got64 := complex64(got)
- if complex128(got64) != test.out {
- t.Fatalf("ParseComplex(%q, 64) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
- }
- }
- }
-}
-
-// Issue 42297: allow ParseComplex(s, not_32_or_64) for legacy reasons
-func TestParseComplexIncorrectBitSize(t *testing.T) {
- const s = "1.5e308+1.0e307i"
- const want = 1.5e308 + 1.0e307i
-
- for _, bitSize := range []int{0, 10, 100, 256} {
- c, err := ParseComplex(s, bitSize)
- if err != nil {
- t.Fatalf("ParseComplex(%q, %d) gave error %s", s, bitSize, err)
- }
- if c != want {
- t.Fatalf("ParseComplex(%q, %d) = %g (expected %g)", s, bitSize, c, want)
- }
- }
-}
diff --git a/src/strconv/atof.go b/src/strconv/atof.go
deleted file mode 100644
index c05d298257..0000000000
--- a/src/strconv/atof.go
+++ /dev/null
@@ -1,708 +0,0 @@
-// 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
-
-// decimal to binary floating point conversion.
-// Algorithm:
-// 1) Store input in multiprecision decimal.
-// 2) Multiply/divide decimal by powers of two until in range [0.5, 1)
-// 3) Multiply by 2^precision and round to get mantissa.
-
-import "math"
-
-var optimize = true // set to false to force slow-path conversions for testing
-
-// commonPrefixLenIgnoreCase returns the length of the common
-// prefix of s and prefix, with the character case of s ignored.
-// The prefix argument must be all lower-case.
-func commonPrefixLenIgnoreCase(s, prefix string) int {
- n := min(len(prefix), len(s))
- for i := 0; i < n; i++ {
- c := s[i]
- if 'A' <= c && c <= 'Z' {
- c += 'a' - 'A'
- }
- if c != prefix[i] {
- return i
- }
- }
- return n
-}
-
-// special returns the floating-point value for the special,
-// possibly signed floating-point representations inf, infinity,
-// and NaN. The result is ok if a prefix of s contains one
-// of these representations and n is the length of that prefix.
-// The character case is ignored.
-func special(s string) (f float64, n int, ok bool) {
- if len(s) == 0 {
- return 0, 0, false
- }
- sign := 1
- nsign := 0
- switch s[0] {
- case '+', '-':
- if s[0] == '-' {
- sign = -1
- }
- nsign = 1
- s = s[1:]
- fallthrough
- case 'i', 'I':
- n := commonPrefixLenIgnoreCase(s, "infinity")
- // Anything longer than "inf" is ok, but if we
- // don't have "infinity", only consume "inf".
- if 3 < n && n < 8 {
- n = 3
- }
- if n == 3 || n == 8 {
- return math.Inf(sign), nsign + n, true
- }
- case 'n', 'N':
- if commonPrefixLenIgnoreCase(s, "nan") == 3 {
- return math.NaN(), 3, true
- }
- }
- return 0, 0, false
-}
-
-func (b *decimal) set(s string) (ok bool) {
- i := 0
- b.neg = false
- b.trunc = false
-
- // optional sign
- if i >= len(s) {
- return
- }
- switch s[i] {
- case '+':
- i++
- case '-':
- i++
- b.neg = true
- }
-
- // digits
- sawdot := false
- sawdigits := false
- for ; i < len(s); i++ {
- switch {
- case s[i] == '_':
- // readFloat already checked underscores
- continue
- case s[i] == '.':
- if sawdot {
- return
- }
- sawdot = true
- b.dp = b.nd
- continue
-
- case '0' <= s[i] && s[i] <= '9':
- sawdigits = true
- if s[i] == '0' && b.nd == 0 { // ignore leading zeros
- b.dp--
- continue
- }
- if b.nd < len(b.d) {
- b.d[b.nd] = s[i]
- b.nd++
- } else if s[i] != '0' {
- b.trunc = true
- }
- continue
- }
- break
- }
- if !sawdigits {
- return
- }
- if !sawdot {
- b.dp = b.nd
- }
-
- // optional exponent moves decimal point.
- // if we read a very large, very long number,
- // just be sure to move the decimal point by
- // a lot (say, 100000). it doesn't matter if it's
- // not the exact number.
- if i < len(s) && lower(s[i]) == 'e' {
- i++
- if i >= len(s) {
- return
- }
- esign := 1
- switch s[i] {
- case '+':
- i++
- case '-':
- i++
- esign = -1
- }
- if i >= len(s) || s[i] < '0' || s[i] > '9' {
- return
- }
- e := 0
- for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i++ {
- if s[i] == '_' {
- // readFloat already checked underscores
- continue
- }
- if e < 10000 {
- e = e*10 + int(s[i]) - '0'
- }
- }
- b.dp += e * esign
- }
-
- if i != len(s) {
- return
- }
-
- ok = true
- return
-}
-
-// readFloat reads a decimal or hexadecimal mantissa and exponent from a float
-// string representation in s; the number may be followed by other characters.
-// readFloat reports the number of bytes consumed (i), and whether the number
-// is valid (ok).
-func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex bool, i int, ok bool) {
- underscores := false
-
- // optional sign
- if i >= len(s) {
- return
- }
- switch s[i] {
- case '+':
- i++
- case '-':
- i++
- neg = true
- }
-
- // digits
- base := uint64(10)
- maxMantDigits := 19 // 10^19 fits in uint64
- expChar := byte('e')
- if i+2 < len(s) && s[i] == '0' && lower(s[i+1]) == 'x' {
- base = 16
- maxMantDigits = 16 // 16^16 fits in uint64
- i += 2
- expChar = 'p'
- hex = true
- }
- sawdot := false
- sawdigits := false
- nd := 0
- ndMant := 0
- dp := 0
-loop:
- for ; i < len(s); i++ {
- switch c := s[i]; true {
- case c == '_':
- underscores = true
- continue
-
- case c == '.':
- if sawdot {
- break loop
- }
- sawdot = true
- dp = nd
- continue
-
- case '0' <= c && c <= '9':
- sawdigits = true
- if c == '0' && nd == 0 { // ignore leading zeros
- dp--
- continue
- }
- nd++
- if ndMant < maxMantDigits {
- mantissa *= base
- mantissa += uint64(c - '0')
- ndMant++
- } else if c != '0' {
- trunc = true
- }
- continue
-
- case base == 16 && 'a' <= lower(c) && lower(c) <= 'f':
- sawdigits = true
- nd++
- if ndMant < maxMantDigits {
- mantissa *= 16
- mantissa += uint64(lower(c) - 'a' + 10)
- ndMant++
- } else {
- trunc = true
- }
- continue
- }
- break
- }
- if !sawdigits {
- return
- }
- if !sawdot {
- dp = nd
- }
-
- if base == 16 {
- dp *= 4
- ndMant *= 4
- }
-
- // optional exponent moves decimal point.
- // if we read a very large, very long number,
- // just be sure to move the decimal point by
- // a lot (say, 100000). it doesn't matter if it's
- // not the exact number.
- if i < len(s) && lower(s[i]) == expChar {
- i++
- if i >= len(s) {
- return
- }
- esign := 1
- switch s[i] {
- case '+':
- i++
- case '-':
- i++
- esign = -1
- }
- if i >= len(s) || s[i] < '0' || s[i] > '9' {
- return
- }
- e := 0
- for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i++ {
- if s[i] == '_' {
- underscores = true
- continue
- }
- if e < 10000 {
- e = e*10 + int(s[i]) - '0'
- }
- }
- dp += e * esign
- } else if base == 16 {
- // Must have exponent.
- return
- }
-
- if mantissa != 0 {
- exp = dp - ndMant
- }
-
- if underscores && !underscoreOK(s[:i]) {
- return
- }
-
- ok = true
- return
-}
-
-// decimal power of ten to binary power of two.
-var powtab = []int{1, 3, 6, 9, 13, 16, 19, 23, 26}
-
-func (d *decimal) floatBits(flt *floatInfo) (b uint64, overflow bool) {
- var exp int
- var mant uint64
-
- // Zero is always a special case.
- if d.nd == 0 {
- mant = 0
- exp = flt.bias
- goto out
- }
-
- // Obvious overflow/underflow.
- // These bounds are for 64-bit floats.
- // Will have to change if we want to support 80-bit floats in the future.
- if d.dp > 310 {
- goto overflow
- }
- if d.dp < -330 {
- // zero
- mant = 0
- exp = flt.bias
- goto out
- }
-
- // Scale by powers of two until in range [0.5, 1.0)
- exp = 0
- for d.dp > 0 {
- var n int
- if d.dp >= len(powtab) {
- n = 27
- } else {
- n = powtab[d.dp]
- }
- d.Shift(-n)
- exp += n
- }
- for d.dp < 0 || d.dp == 0 && d.d[0] < '5' {
- var n int
- if -d.dp >= len(powtab) {
- n = 27
- } else {
- n = powtab[-d.dp]
- }
- d.Shift(n)
- exp -= n
- }
-
- // Our range is [0.5,1) but floating point range is [1,2).
- exp--
-
- // Minimum representable exponent is flt.bias+1.
- // If the exponent is smaller, move it up and
- // adjust d accordingly.
- if exp < flt.bias+1 {
- n := flt.bias + 1 - exp
- d.Shift(-n)
- exp += n
- }
-
- if exp-flt.bias >= 1<<flt.expbits-1 {
- goto overflow
- }
-
- // Extract 1+flt.mantbits bits.
- d.Shift(int(1 + flt.mantbits))
- mant = d.RoundedInteger()
-
- // Rounding might have added a bit; shift down.
- if mant == 2<<flt.mantbits {
- mant >>= 1
- exp++
- if exp-flt.bias >= 1<<flt.expbits-1 {
- goto overflow
- }
- }
-
- // Denormalized?
- if mant&(1<<flt.mantbits) == 0 {
- exp = flt.bias
- }
- goto out
-
-overflow:
- // ±Inf
- mant = 0
- exp = 1<<flt.expbits - 1 + flt.bias
- overflow = true
-
-out:
- // Assemble bits.
- bits := mant & (uint64(1)<<flt.mantbits - 1)
- bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits
- if d.neg {
- bits |= 1 << flt.mantbits << flt.expbits
- }
- return bits, overflow
-}
-
-// Exact powers of 10.
-var float64pow10 = []float64{
- 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
- 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
- 1e20, 1e21, 1e22,
-}
-var float32pow10 = []float32{1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10}
-
-// If possible to convert decimal representation to 64-bit float f exactly,
-// entirely in floating-point math, do so, avoiding the expense of decimalToFloatBits.
-// Three common cases:
-//
-// value is exact integer
-// value is exact integer * exact power of ten
-// value is exact integer / exact power of ten
-//
-// These all produce potentially inexact but correctly rounded answers.
-func atof64exact(mantissa uint64, exp int, neg bool) (f float64, ok bool) {
- if mantissa>>float64info.mantbits != 0 {
- return
- }
- f = float64(mantissa)
- if neg {
- f = -f
- }
- switch {
- case exp == 0:
- // an integer.
- return f, true
- // Exact integers are <= 10^15.
- // Exact powers of ten are <= 10^22.
- case exp > 0 && exp <= 15+22: // int * 10^k
- // If exponent is big but number of digits is not,
- // can move a few zeros into the integer part.
- if exp > 22 {
- f *= float64pow10[exp-22]
- exp = 22
- }
- if f > 1e15 || f < -1e15 {
- // the exponent was really too large.
- return
- }
- return f * float64pow10[exp], true
- case exp < 0 && exp >= -22: // int / 10^k
- return f / float64pow10[-exp], true
- }
- return
-}
-
-// If possible to compute mantissa*10^exp to 32-bit float f exactly,
-// entirely in floating-point math, do so, avoiding the machinery above.
-func atof32exact(mantissa uint64, exp int, neg bool) (f float32, ok bool) {
- if mantissa>>float32MantBits != 0 {
- return
- }
- f = float32(mantissa)
- if neg {
- f = -f
- }
- switch {
- case exp == 0:
- return f, true
- // Exact integers are <= 10^7.
- // Exact powers of ten are <= 10^10.
- case exp > 0 && exp <= 7+10: // int * 10^k
- // If exponent is big but number of digits is not,
- // can move a few zeros into the integer part.
- if exp > 10 {
- f *= float32pow10[exp-10]
- exp = 10
- }
- if f > 1e7 || f < -1e7 {
- // the exponent was really too large.
- return
- }
- return f * float32pow10[exp], true
- case exp < 0 && exp >= -10: // int / 10^k
- return f / float32pow10[-exp], true
- }
- return
-}
-
-// atofHex converts the hex floating-point string s
-// to a rounded float32 or float64 value (depending on flt==&float32info or flt==&float64info)
-// and returns it as a float64.
-// The string s has already been parsed into a mantissa, exponent, and sign (neg==true for negative).
-// If trunc is true, trailing non-zero bits have been omitted from the mantissa.
-func atofHex(s string, flt *floatInfo, mantissa uint64, exp int, neg, trunc bool) (float64, error) {
- maxExp := 1<<flt.expbits + flt.bias - 2
- minExp := flt.bias + 1
- exp += int(flt.mantbits) // mantissa now implicitly divided by 2^mantbits.
-
- // Shift mantissa and exponent to bring representation into float range.
- // Eventually we want a mantissa with a leading 1-bit followed by mantbits other bits.
- // For rounding, we need two more, where the bottom bit represents
- // whether that bit or any later bit was non-zero.
- // (If the mantissa has already lost non-zero bits, trunc is true,
- // and we OR in a 1 below after shifting left appropriately.)
- for mantissa != 0 && mantissa>>(flt.mantbits+2) == 0 {
- mantissa <<= 1
- exp--
- }
- if trunc {
- mantissa |= 1
- }
- for mantissa>>(1+flt.mantbits+2) != 0 {
- mantissa = mantissa>>1 | mantissa&1
- exp++
- }
-
- // If exponent is too negative,
- // denormalize in hopes of making it representable.
- // (The -2 is for the rounding bits.)
- for mantissa > 1 && exp < minExp-2 {
- mantissa = mantissa>>1 | mantissa&1
- exp++
- }
-
- // Round using two bottom bits.
- round := mantissa & 3
- mantissa >>= 2
- round |= mantissa & 1 // round to even (round up if mantissa is odd)
- exp += 2
- if round == 3 {
- mantissa++
- if mantissa == 1<<(1+flt.mantbits) {
- mantissa >>= 1
- exp++
- }
- }
-
- if mantissa>>flt.mantbits == 0 { // Denormal or zero.
- exp = flt.bias
- }
- var err error
- if exp > maxExp { // infinity and range error
- mantissa = 1 << flt.mantbits
- exp = maxExp + 1
- err = rangeError(fnParseFloat, s)
- }
-
- bits := mantissa & (1<<flt.mantbits - 1)
- bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits
- if neg {
- bits |= 1 << flt.mantbits << flt.expbits
- }
- if flt == &float32info {
- return float64(math.Float32frombits(uint32(bits))), err
- }
- return math.Float64frombits(bits), err
-}
-
-const fnParseFloat = "ParseFloat"
-
-func atof32(s string) (f float32, n int, err error) {
- if val, n, ok := special(s); ok {
- return float32(val), n, nil
- }
-
- mantissa, exp, neg, trunc, hex, n, ok := readFloat(s)
- if !ok {
- return 0, n, syntaxError(fnParseFloat, s)
- }
-
- if hex {
- f, err := atofHex(s[:n], &float32info, mantissa, exp, neg, trunc)
- return float32(f), n, err
- }
-
- if optimize {
- // Try pure floating-point arithmetic conversion, and if that fails,
- // the Eisel-Lemire algorithm.
- if !trunc {
- if f, ok := atof32exact(mantissa, exp, neg); ok {
- return f, n, nil
- }
- }
- f, ok := eiselLemire32(mantissa, exp, neg)
- if ok {
- if !trunc {
- return f, n, nil
- }
- // Even if the mantissa was truncated, we may
- // have found the correct result. Confirm by
- // converting the upper mantissa bound.
- fUp, ok := eiselLemire32(mantissa+1, exp, neg)
- if ok && f == fUp {
- return f, n, nil
- }
- }
- }
-
- // Slow fallback.
- var d decimal
- if !d.set(s[:n]) {
- return 0, n, syntaxError(fnParseFloat, s)
- }
- b, ovf := d.floatBits(&float32info)
- f = math.Float32frombits(uint32(b))
- if ovf {
- err = rangeError(fnParseFloat, s)
- }
- return f, n, err
-}
-
-func atof64(s string) (f float64, n int, err error) {
- if val, n, ok := special(s); ok {
- return val, n, nil
- }
-
- mantissa, exp, neg, trunc, hex, n, ok := readFloat(s)
- if !ok {
- return 0, n, syntaxError(fnParseFloat, s)
- }
-
- if hex {
- f, err := atofHex(s[:n], &float64info, mantissa, exp, neg, trunc)
- return f, n, err
- }
-
- if optimize {
- // Try pure floating-point arithmetic conversion, and if that fails,
- // the Eisel-Lemire algorithm.
- if !trunc {
- if f, ok := atof64exact(mantissa, exp, neg); ok {
- return f, n, nil
- }
- }
- f, ok := eiselLemire64(mantissa, exp, neg)
- if ok {
- if !trunc {
- return f, n, nil
- }
- // Even if the mantissa was truncated, we may
- // have found the correct result. Confirm by
- // converting the upper mantissa bound.
- fUp, ok := eiselLemire64(mantissa+1, exp, neg)
- if ok && f == fUp {
- return f, n, nil
- }
- }
- }
-
- // Slow fallback.
- var d decimal
- if !d.set(s[:n]) {
- return 0, n, syntaxError(fnParseFloat, s)
- }
- b, ovf := d.floatBits(&float64info)
- f = math.Float64frombits(b)
- if ovf {
- err = rangeError(fnParseFloat, s)
- }
- return f, n, err
-}
-
-// ParseFloat converts the string s to a floating-point number
-// with the precision specified by bitSize: 32 for float32, or 64 for float64.
-// When bitSize=32, the result still has type float64, but it will be
-// convertible to float32 without changing its value.
-//
-// ParseFloat accepts decimal and hexadecimal floating-point numbers
-// as defined by the Go syntax for [floating-point literals].
-// If s is well-formed and near a valid floating-point number,
-// ParseFloat returns the nearest floating-point number rounded
-// using IEEE754 unbiased rounding.
-// (Parsing a hexadecimal floating-point value only rounds when
-// there are more bits in the hexadecimal representation than
-// will fit in the mantissa.)
-//
-// The errors that ParseFloat returns have concrete type *NumError
-// and include err.Num = s.
-//
-// If s is not syntactically well-formed, ParseFloat returns err.Err = ErrSyntax.
-//
-// If s is syntactically well-formed but is more than 1/2 ULP
-// away from the largest floating point number of the given size,
-// ParseFloat returns f = ±Inf, err.Err = ErrRange.
-//
-// ParseFloat recognizes the string "NaN", and the (possibly signed) strings "Inf" and "Infinity"
-// as their respective special floating point values. It ignores case when matching.
-//
-// [floating-point literals]: https://go.dev/ref/spec#Floating-point_literals
-func ParseFloat(s string, bitSize int) (float64, error) {
- f, n, err := parseFloatPrefix(s, bitSize)
- if n != len(s) && (err == nil || err.(*NumError).Err != ErrSyntax) {
- return 0, syntaxError(fnParseFloat, s)
- }
- return f, err
-}
-
-func parseFloatPrefix(s string, bitSize int) (float64, int, error) {
- if bitSize == 32 {
- f, n, err := atof32(s)
- return float64(f), n, err
- }
- return atof64(s)
-}
diff --git a/src/strconv/atof_test.go b/src/strconv/atof_test.go
deleted file mode 100644
index 7b287b4219..0000000000
--- a/src/strconv/atof_test.go
+++ /dev/null
@@ -1,754 +0,0 @@
-// 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 (
- "math"
- "math/rand"
- "reflect"
- . "strconv"
- "strings"
- "sync"
- "testing"
-)
-
-type atofTest struct {
- in string
- out string
- err error
-}
-
-var atoftests = []atofTest{
- {"", "0", ErrSyntax},
- {"1", "1", nil},
- {"+1", "1", nil},
- {"1x", "0", ErrSyntax},
- {"1.1.", "0", ErrSyntax},
- {"1e23", "1e+23", nil},
- {"1E23", "1e+23", nil},
- {"100000000000000000000000", "1e+23", nil},
- {"1e-100", "1e-100", nil},
- {"123456700", "1.234567e+08", nil},
- {"99999999999999974834176", "9.999999999999997e+22", nil},
- {"100000000000000000000001", "1.0000000000000001e+23", nil},
- {"100000000000000008388608", "1.0000000000000001e+23", nil},
- {"100000000000000016777215", "1.0000000000000001e+23", nil},
- {"100000000000000016777216", "1.0000000000000003e+23", nil},
- {"-1", "-1", nil},
- {"-0.1", "-0.1", nil},
- {"-0", "-0", nil},
- {"1e-20", "1e-20", nil},
- {"625e-3", "0.625", nil},
-
- // Hexadecimal floating-point.
- {"0x1p0", "1", nil},
- {"0x1p1", "2", nil},
- {"0x1p-1", "0.5", nil},
- {"0x1ep-1", "15", nil},
- {"-0x1ep-1", "-15", nil},
- {"-0x1_ep-1", "-15", nil},
- {"0x1p-200", "6.223015277861142e-61", nil},
- {"0x1p200", "1.6069380442589903e+60", nil},
- {"0x1fFe2.p0", "131042", nil},
- {"0x1fFe2.P0", "131042", nil},
- {"-0x2p3", "-16", nil},
- {"0x0.fp4", "15", nil},
- {"0x0.fp0", "0.9375", nil},
- {"0x1e2", "0", ErrSyntax},
- {"1p2", "0", ErrSyntax},
-
- // zeros
- {"0", "0", nil},
- {"0e0", "0", nil},
- {"-0e0", "-0", nil},
- {"+0e0", "0", nil},
- {"0e-0", "0", nil},
- {"-0e-0", "-0", nil},
- {"+0e-0", "0", nil},
- {"0e+0", "0", nil},
- {"-0e+0", "-0", nil},
- {"+0e+0", "0", nil},
- {"0e+01234567890123456789", "0", nil},
- {"0.00e-01234567890123456789", "0", nil},
- {"-0e+01234567890123456789", "-0", nil},
- {"-0.00e-01234567890123456789", "-0", nil},
- {"0x0p+01234567890123456789", "0", nil},
- {"0x0.00p-01234567890123456789", "0", nil},
- {"-0x0p+01234567890123456789", "-0", nil},
- {"-0x0.00p-01234567890123456789", "-0", nil},
-
- {"0e291", "0", nil}, // issue 15364
- {"0e292", "0", nil}, // issue 15364
- {"0e347", "0", nil}, // issue 15364
- {"0e348", "0", nil}, // issue 15364
- {"-0e291", "-0", nil},
- {"-0e292", "-0", nil},
- {"-0e347", "-0", nil},
- {"-0e348", "-0", nil},
- {"0x0p126", "0", nil},
- {"0x0p127", "0", nil},
- {"0x0p128", "0", nil},
- {"0x0p129", "0", nil},
- {"0x0p130", "0", nil},
- {"0x0p1022", "0", nil},
- {"0x0p1023", "0", nil},
- {"0x0p1024", "0", nil},
- {"0x0p1025", "0", nil},
- {"0x0p1026", "0", nil},
- {"-0x0p126", "-0", nil},
- {"-0x0p127", "-0", nil},
- {"-0x0p128", "-0", nil},
- {"-0x0p129", "-0", nil},
- {"-0x0p130", "-0", nil},
- {"-0x0p1022", "-0", nil},
- {"-0x0p1023", "-0", nil},
- {"-0x0p1024", "-0", nil},
- {"-0x0p1025", "-0", nil},
- {"-0x0p1026", "-0", nil},
-
- // NaNs
- {"nan", "NaN", nil},
- {"NaN", "NaN", nil},
- {"NAN", "NaN", nil},
-
- // Infs
- {"inf", "+Inf", nil},
- {"-Inf", "-Inf", nil},
- {"+INF", "+Inf", nil},
- {"-Infinity", "-Inf", nil},
- {"+INFINITY", "+Inf", nil},
- {"Infinity", "+Inf", nil},
-
- // largest float64
- {"1.7976931348623157e308", "1.7976931348623157e+308", nil},
- {"-1.7976931348623157e308", "-1.7976931348623157e+308", nil},
- {"0x1.fffffffffffffp1023", "1.7976931348623157e+308", nil},
- {"-0x1.fffffffffffffp1023", "-1.7976931348623157e+308", nil},
- {"0x1fffffffffffffp+971", "1.7976931348623157e+308", nil},
- {"-0x1fffffffffffffp+971", "-1.7976931348623157e+308", nil},
- {"0x.1fffffffffffffp1027", "1.7976931348623157e+308", nil},
- {"-0x.1fffffffffffffp1027", "-1.7976931348623157e+308", nil},
-
- // next float64 - too large
- {"1.7976931348623159e308", "+Inf", ErrRange},
- {"-1.7976931348623159e308", "-Inf", ErrRange},
- {"0x1p1024", "+Inf", ErrRange},
- {"-0x1p1024", "-Inf", ErrRange},
- {"0x2p1023", "+Inf", ErrRange},
- {"-0x2p1023", "-Inf", ErrRange},
- {"0x.1p1028", "+Inf", ErrRange},
- {"-0x.1p1028", "-Inf", ErrRange},
- {"0x.2p1027", "+Inf", ErrRange},
- {"-0x.2p1027", "-Inf", ErrRange},
-
- // the border is ...158079
- // borderline - okay
- {"1.7976931348623158e308", "1.7976931348623157e+308", nil},
- {"-1.7976931348623158e308", "-1.7976931348623157e+308", nil},
- {"0x1.fffffffffffff7fffp1023", "1.7976931348623157e+308", nil},
- {"-0x1.fffffffffffff7fffp1023", "-1.7976931348623157e+308", nil},
- // borderline - too large
- {"1.797693134862315808e308", "+Inf", ErrRange},
- {"-1.797693134862315808e308", "-Inf", ErrRange},
- {"0x1.fffffffffffff8p1023", "+Inf", ErrRange},
- {"-0x1.fffffffffffff8p1023", "-Inf", ErrRange},
- {"0x1fffffffffffff.8p+971", "+Inf", ErrRange},
- {"-0x1fffffffffffff8p+967", "-Inf", ErrRange},
- {"0x.1fffffffffffff8p1027", "+Inf", ErrRange},
- {"-0x.1fffffffffffff9p1027", "-Inf", ErrRange},
-
- // a little too large
- {"1e308", "1e+308", nil},
- {"2e308", "+Inf", ErrRange},
- {"1e309", "+Inf", ErrRange},
- {"0x1p1025", "+Inf", ErrRange},
-
- // way too large
- {"1e310", "+Inf", ErrRange},
- {"-1e310", "-Inf", ErrRange},
- {"1e400", "+Inf", ErrRange},
- {"-1e400", "-Inf", ErrRange},
- {"1e400000", "+Inf", ErrRange},
- {"-1e400000", "-Inf", ErrRange},
- {"0x1p1030", "+Inf", ErrRange},
- {"0x1p2000", "+Inf", ErrRange},
- {"0x1p2000000000", "+Inf", ErrRange},
- {"-0x1p1030", "-Inf", ErrRange},
- {"-0x1p2000", "-Inf", ErrRange},
- {"-0x1p2000000000", "-Inf", ErrRange},
-
- // denormalized
- {"1e-305", "1e-305", nil},
- {"1e-306", "1e-306", nil},
- {"1e-307", "1e-307", nil},
- {"1e-308", "1e-308", nil},
- {"1e-309", "1e-309", nil},
- {"1e-310", "1e-310", nil},
- {"1e-322", "1e-322", nil},
- // smallest denormal
- {"5e-324", "5e-324", nil},
- {"4e-324", "5e-324", nil},
- {"3e-324", "5e-324", nil},
- // too small
- {"2e-324", "0", nil},
- // way too small
- {"1e-350", "0", nil},
- {"1e-400000", "0", nil},
-
- // Near denormals and denormals.
- {"0x2.00000000000000p-1010", "1.8227805048890994e-304", nil}, // 0x00e0000000000000
- {"0x1.fffffffffffff0p-1010", "1.8227805048890992e-304", nil}, // 0x00dfffffffffffff
- {"0x1.fffffffffffff7p-1010", "1.8227805048890992e-304", nil}, // rounded down
- {"0x1.fffffffffffff8p-1010", "1.8227805048890994e-304", nil}, // rounded up
- {"0x1.fffffffffffff9p-1010", "1.8227805048890994e-304", nil}, // rounded up
-
- {"0x2.00000000000000p-1022", "4.450147717014403e-308", nil}, // 0x0020000000000000
- {"0x1.fffffffffffff0p-1022", "4.4501477170144023e-308", nil}, // 0x001fffffffffffff
- {"0x1.fffffffffffff7p-1022", "4.4501477170144023e-308", nil}, // rounded down
- {"0x1.fffffffffffff8p-1022", "4.450147717014403e-308", nil}, // rounded up
- {"0x1.fffffffffffff9p-1022", "4.450147717014403e-308", nil}, // rounded up
-
- {"0x1.00000000000000p-1022", "2.2250738585072014e-308", nil}, // 0x0010000000000000
- {"0x0.fffffffffffff0p-1022", "2.225073858507201e-308", nil}, // 0x000fffffffffffff
- {"0x0.ffffffffffffe0p-1022", "2.2250738585072004e-308", nil}, // 0x000ffffffffffffe
- {"0x0.ffffffffffffe7p-1022", "2.2250738585072004e-308", nil}, // rounded down
- {"0x1.ffffffffffffe8p-1023", "2.225073858507201e-308", nil}, // rounded up
- {"0x1.ffffffffffffe9p-1023", "2.225073858507201e-308", nil}, // rounded up
-
- {"0x0.00000003fffff0p-1022", "2.072261e-317", nil}, // 0x00000000003fffff
- {"0x0.00000003456780p-1022", "1.694649e-317", nil}, // 0x0000000000345678
- {"0x0.00000003456787p-1022", "1.694649e-317", nil}, // rounded down
- {"0x0.00000003456788p-1022", "1.694649e-317", nil}, // rounded down (half to even)
- {"0x0.00000003456790p-1022", "1.6946496e-317", nil}, // 0x0000000000345679
- {"0x0.00000003456789p-1022", "1.6946496e-317", nil}, // rounded up
-
- {"0x0.0000000345678800000000000000000000000001p-1022", "1.6946496e-317", nil}, // rounded up
-
- {"0x0.000000000000f0p-1022", "7.4e-323", nil}, // 0x000000000000000f
- {"0x0.00000000000060p-1022", "3e-323", nil}, // 0x0000000000000006
- {"0x0.00000000000058p-1022", "3e-323", nil}, // rounded up
- {"0x0.00000000000057p-1022", "2.5e-323", nil}, // rounded down
- {"0x0.00000000000050p-1022", "2.5e-323", nil}, // 0x0000000000000005
-
- {"0x0.00000000000010p-1022", "5e-324", nil}, // 0x0000000000000001
- {"0x0.000000000000081p-1022", "5e-324", nil}, // rounded up
- {"0x0.00000000000008p-1022", "0", nil}, // rounded down
- {"0x0.00000000000007fp-1022", "0", nil}, // rounded down
-
- // try to overflow exponent
- {"1e-4294967296", "0", nil},
- {"1e+4294967296", "+Inf", ErrRange},
- {"1e-18446744073709551616", "0", nil},
- {"1e+18446744073709551616", "+Inf", ErrRange},
- {"0x1p-4294967296", "0", nil},
- {"0x1p+4294967296", "+Inf", ErrRange},
- {"0x1p-18446744073709551616", "0", nil},
- {"0x1p+18446744073709551616", "+Inf", ErrRange},
-
- // Parse errors
- {"1e", "0", ErrSyntax},
- {"1e-", "0", ErrSyntax},
- {".e-1", "0", ErrSyntax},
- {"1\x00.2", "0", ErrSyntax},
- {"0x", "0", ErrSyntax},
- {"0x.", "0", ErrSyntax},
- {"0x1", "0", ErrSyntax},
- {"0x.1", "0", ErrSyntax},
- {"0x1p", "0", ErrSyntax},
- {"0x.1p", "0", ErrSyntax},
- {"0x1p+", "0", ErrSyntax},
- {"0x.1p+", "0", ErrSyntax},
- {"0x1p-", "0", ErrSyntax},
- {"0x.1p-", "0", ErrSyntax},
- {"0x1p+2", "4", nil},
- {"0x.1p+2", "0.25", nil},
- {"0x1p-2", "0.25", nil},
- {"0x.1p-2", "0.015625", nil},
-
- // https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
- {"2.2250738585072012e-308", "2.2250738585072014e-308", nil},
- // https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
- {"2.2250738585072011e-308", "2.225073858507201e-308", nil},
-
- // A very large number (initially wrongly parsed by the fast algorithm).
- {"4.630813248087435e+307", "4.630813248087435e+307", nil},
-
- // A different kind of very large number.
- {"22.222222222222222", "22.22222222222222", nil},
- {"2." + strings.Repeat("2", 4000) + "e+1", "22.22222222222222", nil},
- {"0x1.1111111111111p222", "7.18931911124017e+66", nil},
- {"0x2.2222222222222p221", "7.18931911124017e+66", nil},
- {"0x2." + strings.Repeat("2", 4000) + "p221", "7.18931911124017e+66", nil},
-
- // Exactly halfway between 1 and math.Nextafter(1, 2).
- // Round to even (down).
- {"1.00000000000000011102230246251565404236316680908203125", "1", nil},
- {"0x1.00000000000008p0", "1", nil},
- // Slightly lower; still round down.
- {"1.00000000000000011102230246251565404236316680908203124", "1", nil},
- {"0x1.00000000000007Fp0", "1", nil},
- // Slightly higher; round up.
- {"1.00000000000000011102230246251565404236316680908203126", "1.0000000000000002", nil},
- {"0x1.000000000000081p0", "1.0000000000000002", nil},
- {"0x1.00000000000009p0", "1.0000000000000002", nil},
- // Slightly higher, but you have to read all the way to the end.
- {"1.00000000000000011102230246251565404236316680908203125" + strings.Repeat("0", 10000) + "1", "1.0000000000000002", nil},
- {"0x1.00000000000008" + strings.Repeat("0", 10000) + "1p0", "1.0000000000000002", nil},
-
- // Halfway between x := math.Nextafter(1, 2) and math.Nextafter(x, 2)
- // Round to even (up).
- {"1.00000000000000033306690738754696212708950042724609375", "1.0000000000000004", nil},
- {"0x1.00000000000018p0", "1.0000000000000004", nil},
-
- // Halfway between 1090544144181609278303144771584 and 1090544144181609419040633126912
- // (15497564393479157p+46, should round to even 15497564393479156p+46, issue 36657)
- {"1090544144181609348671888949248", "1.0905441441816093e+30", nil},
- // slightly above, rounds up
- {"1090544144181609348835077142190", "1.0905441441816094e+30", nil},
-
- // Underscores.
- {"1_23.50_0_0e+1_2", "1.235e+14", nil},
- {"-_123.5e+12", "0", ErrSyntax},
- {"+_123.5e+12", "0", ErrSyntax},
- {"_123.5e+12", "0", ErrSyntax},
- {"1__23.5e+12", "0", ErrSyntax},
- {"123_.5e+12", "0", ErrSyntax},
- {"123._5e+12", "0", ErrSyntax},
- {"123.5_e+12", "0", ErrSyntax},
- {"123.5__0e+12", "0", ErrSyntax},
- {"123.5e_+12", "0", ErrSyntax},
- {"123.5e+_12", "0", ErrSyntax},
- {"123.5e_-12", "0", ErrSyntax},
- {"123.5e-_12", "0", ErrSyntax},
- {"123.5e+1__2", "0", ErrSyntax},
- {"123.5e+12_", "0", ErrSyntax},
-
- {"0x_1_2.3_4_5p+1_2", "74565", nil},
- {"-_0x12.345p+12", "0", ErrSyntax},
- {"+_0x12.345p+12", "0", ErrSyntax},
- {"_0x12.345p+12", "0", ErrSyntax},
- {"0x__12.345p+12", "0", ErrSyntax},
- {"0x1__2.345p+12", "0", ErrSyntax},
- {"0x12_.345p+12", "0", ErrSyntax},
- {"0x12._345p+12", "0", ErrSyntax},
- {"0x12.3__45p+12", "0", ErrSyntax},
- {"0x12.345_p+12", "0", ErrSyntax},
- {"0x12.345p_+12", "0", ErrSyntax},
- {"0x12.345p+_12", "0", ErrSyntax},
- {"0x12.345p_-12", "0", ErrSyntax},
- {"0x12.345p-_12", "0", ErrSyntax},
- {"0x12.345p+1__2", "0", ErrSyntax},
- {"0x12.345p+12_", "0", ErrSyntax},
-
- {"1e100x", "0", ErrSyntax},
- {"1e1000x", "0", ErrSyntax},
-}
-
-var atof32tests = []atofTest{
- // Hex
- {"0x1p-100", "7.888609e-31", nil},
- {"0x1p100", "1.2676506e+30", nil},
-
- // Exactly halfway between 1 and the next float32.
- // Round to even (down).
- {"1.000000059604644775390625", "1", nil},
- {"0x1.000001p0", "1", nil},
- // Slightly lower.
- {"1.000000059604644775390624", "1", nil},
- {"0x1.0000008p0", "1", nil},
- {"0x1.000000fp0", "1", nil},
- // Slightly higher.
- {"1.000000059604644775390626", "1.0000001", nil},
- {"0x1.000002p0", "1.0000001", nil},
- {"0x1.0000018p0", "1.0000001", nil},
- {"0x1.0000011p0", "1.0000001", nil},
- // Slightly higher, but you have to read all the way to the end.
- {"1.000000059604644775390625" + strings.Repeat("0", 10000) + "1", "1.0000001", nil},
- {"0x1.000001" + strings.Repeat("0", 10000) + "1p0", "1.0000001", nil},
-
- // largest float32: (1<<128) * (1 - 2^-24)
- {"340282346638528859811704183484516925440", "3.4028235e+38", nil},
- {"-340282346638528859811704183484516925440", "-3.4028235e+38", nil},
- {"0x.ffffffp128", "3.4028235e+38", nil},
- {"-340282346638528859811704183484516925440", "-3.4028235e+38", nil},
- {"-0x.ffffffp128", "-3.4028235e+38", nil},
- // next float32 - too large
- {"3.4028236e38", "+Inf", ErrRange},
- {"-3.4028236e38", "-Inf", ErrRange},
- {"0x1.0p128", "+Inf", ErrRange},
- {"-0x1.0p128", "-Inf", ErrRange},
- // the border is 3.40282356779...e+38
- // borderline - okay
- {"3.402823567e38", "3.4028235e+38", nil},
- {"-3.402823567e38", "-3.4028235e+38", nil},
- {"0x.ffffff7fp128", "3.4028235e+38", nil},
- {"-0x.ffffff7fp128", "-3.4028235e+38", nil},
- // borderline - too large
- {"3.4028235678e38", "+Inf", ErrRange},
- {"-3.4028235678e38", "-Inf", ErrRange},
- {"0x.ffffff8p128", "+Inf", ErrRange},
- {"-0x.ffffff8p128", "-Inf", ErrRange},
-
- // Denormals: less than 2^-126
- {"1e-38", "1e-38", nil},
- {"1e-39", "1e-39", nil},
- {"1e-40", "1e-40", nil},
- {"1e-41", "1e-41", nil},
- {"1e-42", "1e-42", nil},
- {"1e-43", "1e-43", nil},
- {"1e-44", "1e-44", nil},
- {"6e-45", "6e-45", nil}, // 4p-149 = 5.6e-45
- {"5e-45", "6e-45", nil},
-
- // Smallest denormal
- {"1e-45", "1e-45", nil}, // 1p-149 = 1.4e-45
- {"2e-45", "1e-45", nil},
- {"3e-45", "3e-45", nil},
-
- // Near denormals and denormals.
- {"0x0.89aBcDp-125", "1.2643093e-38", nil}, // 0x0089abcd
- {"0x0.8000000p-125", "1.1754944e-38", nil}, // 0x00800000
- {"0x0.1234560p-125", "1.671814e-39", nil}, // 0x00123456
- {"0x0.1234567p-125", "1.671814e-39", nil}, // rounded down
- {"0x0.1234568p-125", "1.671814e-39", nil}, // rounded down
- {"0x0.1234569p-125", "1.671815e-39", nil}, // rounded up
- {"0x0.1234570p-125", "1.671815e-39", nil}, // 0x00123457
- {"0x0.0000010p-125", "1e-45", nil}, // 0x00000001
- {"0x0.00000081p-125", "1e-45", nil}, // rounded up
- {"0x0.0000008p-125", "0", nil}, // rounded down
- {"0x0.0000007p-125", "0", nil}, // rounded down
-
- // 2^92 = 8388608p+69 = 4951760157141521099596496896 (4.9517602e27)
- // is an exact power of two that needs 8 decimal digits to be correctly
- // parsed back.
- // The float32 before is 16777215p+68 = 4.95175986e+27
- // The halfway is 4.951760009. A bad algorithm that thinks the previous
- // float32 is 8388607p+69 will shorten incorrectly to 4.95176e+27.
- {"4951760157141521099596496896", "4.9517602e+27", nil},
-}
-
-type atofSimpleTest struct {
- x float64
- s string
-}
-
-var (
- atofOnce sync.Once
- atofRandomTests []atofSimpleTest
- benchmarksRandomBits [1024]string
- benchmarksRandomNormal [1024]string
-)
-
-func initAtof() {
- atofOnce.Do(initAtofOnce)
-}
-
-func initAtofOnce() {
- // The atof routines return NumErrors wrapping
- // the error and the string. Convert the table above.
- for i := range atoftests {
- test := &atoftests[i]
- if test.err != nil {
- test.err = &NumError{"ParseFloat", test.in, test.err}
- }
- }
- for i := range atof32tests {
- test := &atof32tests[i]
- if test.err != nil {
- test.err = &NumError{"ParseFloat", test.in, test.err}
- }
- }
-
- // Generate random inputs for tests and benchmarks
- if testing.Short() {
- atofRandomTests = make([]atofSimpleTest, 100)
- } else {
- atofRandomTests = make([]atofSimpleTest, 10000)
- }
- for i := range atofRandomTests {
- n := uint64(rand.Uint32())<<32 | uint64(rand.Uint32())
- x := math.Float64frombits(n)
- s := FormatFloat(x, 'g', -1, 64)
- atofRandomTests[i] = atofSimpleTest{x, s}
- }
-
- for i := range benchmarksRandomBits {
- bits := uint64(rand.Uint32())<<32 | uint64(rand.Uint32())
- x := math.Float64frombits(bits)
- benchmarksRandomBits[i] = FormatFloat(x, 'g', -1, 64)
- }
-
- for i := range benchmarksRandomNormal {
- x := rand.NormFloat64()
- benchmarksRandomNormal[i] = FormatFloat(x, 'g', -1, 64)
- }
-}
-
-func TestParseFloatPrefix(t *testing.T) {
- for i := range atoftests {
- test := &atoftests[i]
- if test.err != nil {
- continue
- }
- // Adding characters that do not extend a number should not invalidate it.
- // Test a few. The "i" and "init" cases test that we accept "infi", "infinit"
- // correctly as "inf" with suffix.
- for _, suffix := range []string{" ", "q", "+", "-", "<", "=", ">", "(", ")", "i", "init"} {
- in := test.in + suffix
- _, n, err := ParseFloatPrefix(in, 64)
- if err != nil {
- t.Errorf("ParseFloatPrefix(%q, 64): err = %v; want no error", in, err)
- }
- if n != len(test.in) {
- t.Errorf("ParseFloatPrefix(%q, 64): n = %d; want %d", in, n, len(test.in))
- }
- }
- }
-}
-
-func testAtof(t *testing.T, opt bool) {
- initAtof()
- oldopt := SetOptimize(opt)
- for i := 0; i < len(atoftests); i++ {
- test := &atoftests[i]
- out, err := ParseFloat(test.in, 64)
- outs := FormatFloat(out, 'g', -1, 64)
- if outs != test.out || !reflect.DeepEqual(err, test.err) {
- t.Errorf("ParseFloat(%v, 64) = %v, %v want %v, %v",
- test.in, out, err, test.out, test.err)
- }
-
- if float64(float32(out)) == out {
- out, err := ParseFloat(test.in, 32)
- out32 := float32(out)
- if float64(out32) != out {
- t.Errorf("ParseFloat(%v, 32) = %v, not a float32 (closest is %v)", test.in, out, float64(out32))
- continue
- }
- outs := FormatFloat(float64(out32), 'g', -1, 32)
- if outs != test.out || !reflect.DeepEqual(err, test.err) {
- t.Errorf("ParseFloat(%v, 32) = %v, %v want %v, %v # %v",
- test.in, out32, err, test.out, test.err, out)
- }
- }
- }
- for _, test := range atof32tests {
- out, err := ParseFloat(test.in, 32)
- out32 := float32(out)
- if float64(out32) != out {
- t.Errorf("ParseFloat(%v, 32) = %v, not a float32 (closest is %v)", test.in, out, float64(out32))
- continue
- }
- outs := FormatFloat(float64(out32), 'g', -1, 32)
- if outs != test.out || !reflect.DeepEqual(err, test.err) {
- t.Errorf("ParseFloat(%v, 32) = %v, %v want %v, %v # %v",
- test.in, out32, err, test.out, test.err, out)
- }
- }
- SetOptimize(oldopt)
-}
-
-func TestAtof(t *testing.T) { testAtof(t, true) }
-
-func TestAtofSlow(t *testing.T) { testAtof(t, false) }
-
-func TestAtofRandom(t *testing.T) {
- initAtof()
- for _, test := range atofRandomTests {
- x, _ := ParseFloat(test.s, 64)
- switch {
- default:
- t.Errorf("number %s badly parsed as %b (expected %b)", test.s, x, test.x)
- case x == test.x:
- case math.IsNaN(test.x) && math.IsNaN(x):
- }
- }
- t.Logf("tested %d random numbers", len(atofRandomTests))
-}
-
-var roundTripCases = []struct {
- f float64
- s string
-}{
- // Issue 2917.
- // This test will break the optimized conversion if the
- // FPU is using 80-bit registers instead of 64-bit registers,
- // usually because the operating system initialized the
- // thread with 80-bit precision and the Go runtime didn't
- // fix the FP control word.
- {8865794286000691 << 39, "4.87402195346389e+27"},
- {8865794286000692 << 39, "4.8740219534638903e+27"},
-}
-
-func TestRoundTrip(t *testing.T) {
- for _, tt := range roundTripCases {
- old := SetOptimize(false)
- s := FormatFloat(tt.f, 'g', -1, 64)
- if s != tt.s {
- t.Errorf("no-opt FormatFloat(%b) = %s, want %s", tt.f, s, tt.s)
- }
- f, err := ParseFloat(tt.s, 64)
- if f != tt.f || err != nil {
- t.Errorf("no-opt ParseFloat(%s) = %b, %v want %b, nil", tt.s, f, err, tt.f)
- }
- SetOptimize(true)
- s = FormatFloat(tt.f, 'g', -1, 64)
- if s != tt.s {
- t.Errorf("opt FormatFloat(%b) = %s, want %s", tt.f, s, tt.s)
- }
- f, err = ParseFloat(tt.s, 64)
- if f != tt.f || err != nil {
- t.Errorf("opt ParseFloat(%s) = %b, %v want %b, nil", tt.s, f, err, tt.f)
- }
- SetOptimize(old)
- }
-}
-
-// TestRoundTrip32 tries a fraction of all finite positive float32 values.
-func TestRoundTrip32(t *testing.T) {
- step := uint32(997)
- if testing.Short() {
- step = 99991
- }
- count := 0
- for i := uint32(0); i < 0xff<<23; i += step {
- f := math.Float32frombits(i)
- if i&1 == 1 {
- f = -f // negative
- }
- s := FormatFloat(float64(f), 'g', -1, 32)
-
- parsed, err := ParseFloat(s, 32)
- parsed32 := float32(parsed)
- switch {
- case err != nil:
- t.Errorf("ParseFloat(%q, 32) gave error %s", s, err)
- case float64(parsed32) != parsed:
- t.Errorf("ParseFloat(%q, 32) = %v, not a float32 (nearest is %v)", s, parsed, parsed32)
- case parsed32 != f:
- t.Errorf("ParseFloat(%q, 32) = %b (expected %b)", s, parsed32, f)
- }
- count++
- }
- t.Logf("tested %d float32's", count)
-}
-
-// Issue 42297: a lot of code in the wild accidentally calls ParseFloat(s, 10)
-// or ParseFloat(s, 0), so allow bitSize values other than 32 and 64.
-func TestParseFloatIncorrectBitSize(t *testing.T) {
- const s = "1.5e308"
- const want = 1.5e308
-
- for _, bitSize := range []int{0, 10, 100, 128} {
- f, err := ParseFloat(s, bitSize)
- if err != nil {
- t.Fatalf("ParseFloat(%q, %d) gave error %s", s, bitSize, err)
- }
- if f != want {
- t.Fatalf("ParseFloat(%q, %d) = %g (expected %g)", s, bitSize, f, want)
- }
- }
-}
-
-func BenchmarkAtof64Decimal(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseFloat("33909", 64)
- }
-}
-
-func BenchmarkAtof64Float(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseFloat("339.7784", 64)
- }
-}
-
-func BenchmarkAtof64FloatExp(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseFloat("-5.09e75", 64)
- }
-}
-
-func BenchmarkAtof64Big(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseFloat("123456789123456789123456789", 64)
- }
-}
-
-func BenchmarkAtof64RandomBits(b *testing.B) {
- initAtof()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- ParseFloat(benchmarksRandomBits[i%1024], 64)
- }
-}
-
-func BenchmarkAtof64RandomFloats(b *testing.B) {
- initAtof()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- ParseFloat(benchmarksRandomNormal[i%1024], 64)
- }
-}
-
-func BenchmarkAtof64RandomLongFloats(b *testing.B) {
- initAtof()
- samples := make([]string, len(atofRandomTests))
- for i, t := range atofRandomTests {
- samples[i] = FormatFloat(t.x, 'g', 20, 64)
- }
- b.ResetTimer()
- idx := 0
- for i := 0; i < b.N; i++ {
- ParseFloat(samples[idx], 64)
- idx++
- if idx == len(samples) {
- idx = 0
- }
- }
-}
-
-func BenchmarkAtof32Decimal(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseFloat("33909", 32)
- }
-}
-
-func BenchmarkAtof32Float(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseFloat("339.778", 32)
- }
-}
-
-func BenchmarkAtof32FloatExp(b *testing.B) {
- for i := 0; i < b.N; i++ {
- ParseFloat("12.3456e32", 32)
- }
-}
-
-func BenchmarkAtof32Random(b *testing.B) {
- n := uint32(997)
- var float32strings [4096]string
- for i := range float32strings {
- n = (99991*n + 42) % (0xff << 23)
- float32strings[i] = FormatFloat(float64(math.Float32frombits(n)), 'g', -1, 32)
- }
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- ParseFloat(float32strings[i%4096], 32)
- }
-}
-
-func BenchmarkAtof32RandomLong(b *testing.B) {
- n := uint32(997)
- var float32strings [4096]string
- for i := range float32strings {
- n = (99991*n + 42) % (0xff << 23)
- float32strings[i] = FormatFloat(float64(math.Float32frombits(n)), 'g', 20, 32)
- }
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- ParseFloat(float32strings[i%4096], 32)
- }
-}
diff --git a/src/strconv/atoi.go b/src/strconv/atoi.go
deleted file mode 100644
index 83e931fe24..0000000000
--- a/src/strconv/atoi.go
+++ /dev/null
@@ -1,328 +0,0 @@
-// 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
-
-import (
- "errors"
- "internal/stringslite"
-)
-
-// lower(c) is a lower-case letter if and only if
-// c is either that lower-case letter or the equivalent upper-case letter.
-// Instead of writing c == 'x' || c == 'X' one can write lower(c) == 'x'.
-// Note that lower of non-letters can produce other non-letters.
-func lower(c byte) byte {
- return c | ('x' - 'X')
-}
-
-// ErrRange indicates that a value is out of range for the target type.
-var ErrRange = errors.New("value out of range")
-
-// ErrSyntax indicates that a value does not have the right syntax for the target type.
-var ErrSyntax = errors.New("invalid syntax")
-
-// A NumError records a failed conversion.
-type NumError struct {
- Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat, ParseComplex)
- Num string // the input
- Err error // the reason the conversion failed (e.g. ErrRange, ErrSyntax, etc.)
-}
-
-func (e *NumError) Error() string {
- return "strconv." + e.Func + ": " + "parsing " + Quote(e.Num) + ": " + e.Err.Error()
-}
-
-func (e *NumError) Unwrap() error { return e.Err }
-
-// All ParseXXX functions allow the input string to escape to the error value.
-// This hurts strconv.ParseXXX(string(b)) calls where b is []byte since
-// the conversion from []byte must allocate a string on the heap.
-// If we assume errors are infrequent, then we can avoid escaping the input
-// back to the output by copying it first. This allows the compiler to call
-// strconv.ParseXXX without a heap allocation for most []byte to string
-// conversions, since it can now prove that the string cannot escape Parse.
-
-func syntaxError(fn, str string) *NumError {
- return &NumError{fn, stringslite.Clone(str), ErrSyntax}
-}
-
-func rangeError(fn, str string) *NumError {
- return &NumError{fn, stringslite.Clone(str), ErrRange}
-}
-
-func baseError(fn, str string, base int) *NumError {
- return &NumError{fn, stringslite.Clone(str), errors.New("invalid base " + Itoa(base))}
-}
-
-func bitSizeError(fn, str string, bitSize int) *NumError {
- return &NumError{fn, stringslite.Clone(str), errors.New("invalid bit size " + Itoa(bitSize))}
-}
-
-const intSize = 32 << (^uint(0) >> 63)
-
-// IntSize is the size in bits of an int or uint value.
-const IntSize = intSize
-
-const maxUint64 = 1<<64 - 1
-
-// ParseUint is like [ParseInt] but for unsigned numbers.
-//
-// A sign prefix is not permitted.
-func ParseUint(s string, base int, bitSize int) (uint64, error) {
- const fnParseUint = "ParseUint"
-
- if s == "" {
- return 0, syntaxError(fnParseUint, s)
- }
-
- base0 := base == 0
-
- s0 := s
- switch {
- case 2 <= base && base <= 36:
- // valid base; nothing to do
-
- case base == 0:
- // Look for octal, hex prefix.
- base = 10
- if s[0] == '0' {
- switch {
- case len(s) >= 3 && lower(s[1]) == 'b':
- base = 2
- s = s[2:]
- case len(s) >= 3 && lower(s[1]) == 'o':
- base = 8
- s = s[2:]
- case len(s) >= 3 && lower(s[1]) == 'x':
- base = 16
- s = s[2:]
- default:
- base = 8
- s = s[1:]
- }
- }
-
- default:
- return 0, baseError(fnParseUint, s0, base)
- }
-
- if bitSize == 0 {
- bitSize = IntSize
- } else if bitSize < 0 || bitSize > 64 {
- return 0, bitSizeError(fnParseUint, s0, bitSize)
- }
-
- // Cutoff is the smallest number such that cutoff*base > maxUint64.
- // Use compile-time constants for common cases.
- var cutoff uint64
- switch base {
- case 10:
- cutoff = maxUint64/10 + 1
- case 16:
- cutoff = maxUint64/16 + 1
- default:
- cutoff = maxUint64/uint64(base) + 1
- }
-
- maxVal := uint64(1)<<uint(bitSize) - 1
-
- underscores := false
- var n uint64
- for _, c := range []byte(s) {
- var d byte
- switch {
- case c == '_' && base0:
- underscores = true
- continue
- case '0' <= c && c <= '9':
- d = c - '0'
- case 'a' <= lower(c) && lower(c) <= 'z':
- d = lower(c) - 'a' + 10
- default:
- return 0, syntaxError(fnParseUint, s0)
- }
-
- if d >= byte(base) {
- return 0, syntaxError(fnParseUint, s0)
- }
-
- if n >= cutoff {
- // n*base overflows
- return maxVal, rangeError(fnParseUint, s0)
- }
- n *= uint64(base)
-
- n1 := n + uint64(d)
- if n1 < n || n1 > maxVal {
- // n+d overflows
- return maxVal, rangeError(fnParseUint, s0)
- }
- n = n1
- }
-
- if underscores && !underscoreOK(s0) {
- return 0, syntaxError(fnParseUint, s0)
- }
-
- return n, nil
-}
-
-// ParseInt interprets a string s in the given base (0, 2 to 36) and
-// bit size (0 to 64) and returns the corresponding value i.
-//
-// The string may begin with a leading sign: "+" or "-".
-//
-// If the base argument is 0, the true base is implied by the string's
-// prefix following the sign (if present): 2 for "0b", 8 for "0" or "0o",
-// 16 for "0x", and 10 otherwise. Also, for argument base 0 only,
-// underscore characters are permitted as defined by the Go syntax for
-// [integer literals].
-//
-// The bitSize argument specifies the integer type
-// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
-// correspond to int, int8, int16, int32, and int64.
-// If bitSize is below 0 or above 64, an error is returned.
-//
-// The errors that ParseInt returns have concrete type [*NumError]
-// and include err.Num = s. If s is empty or contains invalid
-// digits, err.Err = [ErrSyntax] and the returned value is 0;
-// if the value corresponding to s cannot be represented by a
-// signed integer of the given size, err.Err = [ErrRange] and the
-// returned value is the maximum magnitude integer of the
-// appropriate bitSize and sign.
-//
-// [integer literals]: https://go.dev/ref/spec#Integer_literals
-func ParseInt(s string, base int, bitSize int) (i int64, err error) {
- const fnParseInt = "ParseInt"
-
- if s == "" {
- return 0, syntaxError(fnParseInt, s)
- }
-
- // Pick off leading sign.
- s0 := s
- neg := false
- switch s[0] {
- case '+':
- s = s[1:]
- case '-':
- s = s[1:]
- neg = true
- }
-
- // Convert unsigned and check range.
- var un uint64
- un, err = ParseUint(s, base, bitSize)
- if err != nil && err.(*NumError).Err != ErrRange {
- err.(*NumError).Func = fnParseInt
- err.(*NumError).Num = stringslite.Clone(s0)
- return 0, err
- }
-
- if bitSize == 0 {
- bitSize = IntSize
- }
-
- cutoff := uint64(1 << uint(bitSize-1))
- if !neg && un >= cutoff {
- return int64(cutoff - 1), rangeError(fnParseInt, s0)
- }
- if neg && un > cutoff {
- return -int64(cutoff), rangeError(fnParseInt, s0)
- }
- n := int64(un)
- if neg {
- n = -n
- }
- return n, nil
-}
-
-// Atoi is equivalent to ParseInt(s, 10, 0), converted to type int.
-func Atoi(s string) (int, error) {
- const fnAtoi = "Atoi"
-
- sLen := len(s)
- if intSize == 32 && (0 < sLen && sLen < 10) ||
- intSize == 64 && (0 < sLen && sLen < 19) {
- // Fast path for small integers that fit int type.
- s0 := s
- if s[0] == '-' || s[0] == '+' {
- s = s[1:]
- if len(s) < 1 {
- return 0, syntaxError(fnAtoi, s0)
- }
- }
-
- n := 0
- for _, ch := range []byte(s) {
- ch -= '0'
- if ch > 9 {
- return 0, syntaxError(fnAtoi, s0)
- }
- n = n*10 + int(ch)
- }
- if s0[0] == '-' {
- n = -n
- }
- return n, nil
- }
-
- // Slow path for invalid, big, or underscored integers.
- i64, err := ParseInt(s, 10, 0)
- if nerr, ok := err.(*NumError); ok {
- nerr.Func = fnAtoi
- }
- return int(i64), err
-}
-
-// underscoreOK reports whether the underscores in s are allowed.
-// Checking them in this one function lets all the parsers skip over them simply.
-// Underscore must appear only between digits or between a base prefix and a digit.
-func underscoreOK(s string) bool {
- // saw tracks the last character (class) we saw:
- // ^ for beginning of number,
- // 0 for a digit or base prefix,
- // _ for an underscore,
- // ! for none of the above.
- saw := '^'
- i := 0
-
- // Optional sign.
- if len(s) >= 1 && (s[0] == '-' || s[0] == '+') {
- s = s[1:]
- }
-
- // Optional base prefix.
- hex := false
- if len(s) >= 2 && s[0] == '0' && (lower(s[1]) == 'b' || lower(s[1]) == 'o' || lower(s[1]) == 'x') {
- i = 2
- saw = '0' // base prefix counts as a digit for "underscore as digit separator"
- hex = lower(s[1]) == 'x'
- }
-
- // Number proper.
- for ; i < len(s); i++ {
- // Digits are always okay.
- if '0' <= s[i] && s[i] <= '9' || hex && 'a' <= lower(s[i]) && lower(s[i]) <= 'f' {
- saw = '0'
- continue
- }
- // Underscore must follow digit.
- if s[i] == '_' {
- if saw != '0' {
- return false
- }
- saw = '_'
- continue
- }
- // Underscore must also be followed by digit.
- if saw == '_' {
- return false
- }
- // Saw non-digit, non-underscore.
- saw = '!'
- }
- return saw != '_'
-}
diff --git a/src/strconv/atoi_test.go b/src/strconv/atoi_test.go
deleted file mode 100644
index ada175200c..0000000000
--- a/src/strconv/atoi_test.go
+++ /dev/null
@@ -1,677 +0,0 @@
-// 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 (
- "errors"
- "fmt"
- "reflect"
- . "strconv"
- "testing"
-)
-
-type parseUint64Test struct {
- in string
- out uint64
- err error
-}
-
-var parseUint64Tests = []parseUint64Test{
- {"", 0, ErrSyntax},
- {"0", 0, nil},
- {"1", 1, nil},
- {"12345", 12345, nil},
- {"012345", 12345, nil},
- {"12345x", 0, ErrSyntax},
- {"98765432100", 98765432100, nil},
- {"18446744073709551615", 1<<64 - 1, nil},
- {"18446744073709551616", 1<<64 - 1, ErrRange},
- {"18446744073709551620", 1<<64 - 1, ErrRange},
- {"1_2_3_4_5", 0, ErrSyntax}, // base=10 so no underscores allowed
- {"_12345", 0, ErrSyntax},
- {"1__2345", 0, ErrSyntax},
- {"12345_", 0, ErrSyntax},
- {"-0", 0, ErrSyntax},
- {"-1", 0, ErrSyntax},
- {"+1", 0, ErrSyntax},
-}
-
-type parseUint64BaseTest struct {
- in string
- base int
- out uint64
- err error
-}
-
-var parseUint64BaseTests = []parseUint64BaseTest{
- {"", 0, 0, ErrSyntax},
- {"0", 0, 0, nil},
- {"0x", 0, 0, ErrSyntax},
- {"0X", 0, 0, ErrSyntax},
- {"1", 0, 1, nil},
- {"12345", 0, 12345, nil},
- {"012345", 0, 012345, nil},
- {"0x12345", 0, 0x12345, nil},
- {"0X12345", 0, 0x12345, nil},
- {"12345x", 0, 0, ErrSyntax},
- {"0xabcdefg123", 0, 0, ErrSyntax},
- {"123456789abc", 0, 0, ErrSyntax},
- {"98765432100", 0, 98765432100, nil},
- {"18446744073709551615", 0, 1<<64 - 1, nil},
- {"18446744073709551616", 0, 1<<64 - 1, ErrRange},
- {"18446744073709551620", 0, 1<<64 - 1, ErrRange},
- {"0xFFFFFFFFFFFFFFFF", 0, 1<<64 - 1, nil},
- {"0x10000000000000000", 0, 1<<64 - 1, ErrRange},
- {"01777777777777777777777", 0, 1<<64 - 1, nil},
- {"01777777777777777777778", 0, 0, ErrSyntax},
- {"02000000000000000000000", 0, 1<<64 - 1, ErrRange},
- {"0200000000000000000000", 0, 1 << 61, nil},
- {"0b", 0, 0, ErrSyntax},
- {"0B", 0, 0, ErrSyntax},
- {"0b101", 0, 5, nil},
- {"0B101", 0, 5, nil},
- {"0o", 0, 0, ErrSyntax},
- {"0O", 0, 0, ErrSyntax},
- {"0o377", 0, 255, nil},
- {"0O377", 0, 255, nil},
-
- // underscores allowed with base == 0 only
- {"1_2_3_4_5", 0, 12345, nil}, // base 0 => 10
- {"_12345", 0, 0, ErrSyntax},
- {"1__2345", 0, 0, ErrSyntax},
- {"12345_", 0, 0, ErrSyntax},
-
- {"1_2_3_4_5", 10, 0, ErrSyntax}, // base 10
- {"_12345", 10, 0, ErrSyntax},
- {"1__2345", 10, 0, ErrSyntax},
- {"12345_", 10, 0, ErrSyntax},
-
- {"0x_1_2_3_4_5", 0, 0x12345, nil}, // base 0 => 16
- {"_0x12345", 0, 0, ErrSyntax},
- {"0x__12345", 0, 0, ErrSyntax},
- {"0x1__2345", 0, 0, ErrSyntax},
- {"0x1234__5", 0, 0, ErrSyntax},
- {"0x12345_", 0, 0, ErrSyntax},
-
- {"1_2_3_4_5", 16, 0, ErrSyntax}, // base 16
- {"_12345", 16, 0, ErrSyntax},
- {"1__2345", 16, 0, ErrSyntax},
- {"1234__5", 16, 0, ErrSyntax},
- {"12345_", 16, 0, ErrSyntax},
-
- {"0_1_2_3_4_5", 0, 012345, nil}, // base 0 => 8 (0377)
- {"_012345", 0, 0, ErrSyntax},
- {"0__12345", 0, 0, ErrSyntax},
- {"01234__5", 0, 0, ErrSyntax},
- {"012345_", 0, 0, ErrSyntax},
-
- {"0o_1_2_3_4_5", 0, 012345, nil}, // base 0 => 8 (0o377)
- {"_0o12345", 0, 0, ErrSyntax},
- {"0o__12345", 0, 0, ErrSyntax},
- {"0o1234__5", 0, 0, ErrSyntax},
- {"0o12345_", 0, 0, ErrSyntax},
-
- {"0_1_2_3_4_5", 8, 0, ErrSyntax}, // base 8
- {"_012345", 8, 0, ErrSyntax},
- {"0__12345", 8, 0, ErrSyntax},
- {"01234__5", 8, 0, ErrSyntax},
- {"012345_", 8, 0, ErrSyntax},
-
- {"0b_1_0_1", 0, 5, nil}, // base 0 => 2 (0b101)
- {"_0b101", 0, 0, ErrSyntax},
- {"0b__101", 0, 0, ErrSyntax},
- {"0b1__01", 0, 0, ErrSyntax},
- {"0b10__1", 0, 0, ErrSyntax},
- {"0b101_", 0, 0, ErrSyntax},
-
- {"1_0_1", 2, 0, ErrSyntax}, // base 2
- {"_101", 2, 0, ErrSyntax},
- {"1_01", 2, 0, ErrSyntax},
- {"10_1", 2, 0, ErrSyntax},
- {"101_", 2, 0, ErrSyntax},
-}
-
-type parseInt64Test struct {
- in string
- out int64
- err error
-}
-
-var parseInt64Tests = []parseInt64Test{
- {"", 0, ErrSyntax},
- {"0", 0, nil},
- {"-0", 0, nil},
- {"+0", 0, nil},
- {"1", 1, nil},
- {"-1", -1, nil},
- {"+1", 1, nil},
- {"12345", 12345, nil},
- {"-12345", -12345, nil},
- {"012345", 12345, nil},
- {"-012345", -12345, nil},
- {"98765432100", 98765432100, nil},
- {"-98765432100", -98765432100, nil},
- {"9223372036854775807", 1<<63 - 1, nil},
- {"-9223372036854775807", -(1<<63 - 1), nil},
- {"9223372036854775808", 1<<63 - 1, ErrRange},
- {"-9223372036854775808", -1 << 63, nil},
- {"9223372036854775809", 1<<63 - 1, ErrRange},
- {"-9223372036854775809", -1 << 63, ErrRange},
- {"-1_2_3_4_5", 0, ErrSyntax}, // base=10 so no underscores allowed
- {"-_12345", 0, ErrSyntax},
- {"_12345", 0, ErrSyntax},
- {"1__2345", 0, ErrSyntax},
- {"12345_", 0, ErrSyntax},
- {"123%45", 0, ErrSyntax},
-}
-
-type parseInt64BaseTest struct {
- in string
- base int
- out int64
- err error
-}
-
-var parseInt64BaseTests = []parseInt64BaseTest{
- {"", 0, 0, ErrSyntax},
- {"0", 0, 0, nil},
- {"-0", 0, 0, nil},
- {"1", 0, 1, nil},
- {"-1", 0, -1, nil},
- {"12345", 0, 12345, nil},
- {"-12345", 0, -12345, nil},
- {"012345", 0, 012345, nil},
- {"-012345", 0, -012345, nil},
- {"0x12345", 0, 0x12345, nil},
- {"-0X12345", 0, -0x12345, nil},
- {"12345x", 0, 0, ErrSyntax},
- {"-12345x", 0, 0, ErrSyntax},
- {"98765432100", 0, 98765432100, nil},
- {"-98765432100", 0, -98765432100, nil},
- {"9223372036854775807", 0, 1<<63 - 1, nil},
- {"-9223372036854775807", 0, -(1<<63 - 1), nil},
- {"9223372036854775808", 0, 1<<63 - 1, ErrRange},
- {"-9223372036854775808", 0, -1 << 63, nil},
- {"9223372036854775809", 0, 1<<63 - 1, ErrRange},
- {"-9223372036854775809", 0, -1 << 63, ErrRange},
-
- // other bases
- {"g", 17, 16, nil},
- {"10", 25, 25, nil},
- {"holycow", 35, (((((17*35+24)*35+21)*35+34)*35+12)*35+24)*35 + 32, nil},
- {"holycow", 36, (((((17*36+24)*36+21)*36+34)*36+12)*36+24)*36 + 32, nil},
-
- // base 2
- {"0", 2, 0, nil},
- {"-1", 2, -1, nil},
- {"1010", 2, 10, nil},
- {"1000000000000000", 2, 1 << 15, nil},
- {"111111111111111111111111111111111111111111111111111111111111111", 2, 1<<63 - 1, nil},
- {"1000000000000000000000000000000000000000000000000000000000000000", 2, 1<<63 - 1, ErrRange},
- {"-1000000000000000000000000000000000000000000000000000000000000000", 2, -1 << 63, nil},
- {"-1000000000000000000000000000000000000000000000000000000000000001", 2, -1 << 63, ErrRange},
-
- // base 8
- {"-10", 8, -8, nil},
- {"57635436545", 8, 057635436545, nil},
- {"100000000", 8, 1 << 24, nil},
-
- // base 16
- {"10", 16, 16, nil},
- {"-123456789abcdef", 16, -0x123456789abcdef, nil},
- {"7fffffffffffffff", 16, 1<<63 - 1, nil},
-
- // underscores
- {"-0x_1_2_3_4_5", 0, -0x12345, nil},
- {"0x_1_2_3_4_5", 0, 0x12345, nil},
- {"-_0x12345", 0, 0, ErrSyntax},
- {"_-0x12345", 0, 0, ErrSyntax},
- {"_0x12345", 0, 0, ErrSyntax},
- {"0x__12345", 0, 0, ErrSyntax},
- {"0x1__2345", 0, 0, ErrSyntax},
- {"0x1234__5", 0, 0, ErrSyntax},
- {"0x12345_", 0, 0, ErrSyntax},
-
- {"-0_1_2_3_4_5", 0, -012345, nil}, // octal
- {"0_1_2_3_4_5", 0, 012345, nil}, // octal
- {"-_012345", 0, 0, ErrSyntax},
- {"_-012345", 0, 0, ErrSyntax},
- {"_012345", 0, 0, ErrSyntax},
- {"0__12345", 0, 0, ErrSyntax},
- {"01234__5", 0, 0, ErrSyntax},
- {"012345_", 0, 0, ErrSyntax},
-
- {"+0xf", 0, 0xf, nil},
- {"-0xf", 0, -0xf, nil},
- {"0x+f", 0, 0, ErrSyntax},
- {"0x-f", 0, 0, ErrSyntax},
-}
-
-type parseUint32Test struct {
- in string
- out uint32
- err error
-}
-
-var parseUint32Tests = []parseUint32Test{
- {"", 0, ErrSyntax},
- {"0", 0, nil},
- {"1", 1, nil},
- {"12345", 12345, nil},
- {"012345", 12345, nil},
- {"12345x", 0, ErrSyntax},
- {"987654321", 987654321, nil},
- {"4294967295", 1<<32 - 1, nil},
- {"4294967296", 1<<32 - 1, ErrRange},
- {"1_2_3_4_5", 0, ErrSyntax}, // base=10 so no underscores allowed
- {"_12345", 0, ErrSyntax},
- {"_12345", 0, ErrSyntax},
- {"1__2345", 0, ErrSyntax},
- {"12345_", 0, ErrSyntax},
-}
-
-type parseInt32Test struct {
- in string
- out int32
- err error
-}
-
-var parseInt32Tests = []parseInt32Test{
- {"", 0, ErrSyntax},
- {"0", 0, nil},
- {"-0", 0, nil},
- {"1", 1, nil},
- {"-1", -1, nil},
- {"12345", 12345, nil},
- {"-12345", -12345, nil},
- {"012345", 12345, nil},
- {"-012345", -12345, nil},
- {"12345x", 0, ErrSyntax},
- {"-12345x", 0, ErrSyntax},
- {"987654321", 987654321, nil},
- {"-987654321", -987654321, nil},
- {"2147483647", 1<<31 - 1, nil},
- {"-2147483647", -(1<<31 - 1), nil},
- {"2147483648", 1<<31 - 1, ErrRange},
- {"-2147483648", -1 << 31, nil},
- {"2147483649", 1<<31 - 1, ErrRange},
- {"-2147483649", -1 << 31, ErrRange},
- {"-1_2_3_4_5", 0, ErrSyntax}, // base=10 so no underscores allowed
- {"-_12345", 0, ErrSyntax},
- {"_12345", 0, ErrSyntax},
- {"1__2345", 0, ErrSyntax},
- {"12345_", 0, ErrSyntax},
- {"123%45", 0, ErrSyntax},
-}
-
-type numErrorTest struct {
- num, want string
-}
-
-var numErrorTests = []numErrorTest{
- {"0", `strconv.ParseFloat: parsing "0": failed`},
- {"`", "strconv.ParseFloat: parsing \"`\": failed"},
- {"1\x00.2", `strconv.ParseFloat: parsing "1\x00.2": failed`},
-}
-
-func init() {
- // The parse routines return NumErrors wrapping
- // the error and the string. Convert the tables above.
- for i := range parseUint64Tests {
- test := &parseUint64Tests[i]
- if test.err != nil {
- test.err = &NumError{"ParseUint", test.in, test.err}
- }
- }
- for i := range parseUint64BaseTests {
- test := &parseUint64BaseTests[i]
- if test.err != nil {
- test.err = &NumError{"ParseUint", test.in, test.err}
- }
- }
- for i := range parseInt64Tests {
- test := &parseInt64Tests[i]
- if test.err != nil {
- test.err = &NumError{"ParseInt", test.in, test.err}
- }
- }
- for i := range parseInt64BaseTests {
- test := &parseInt64BaseTests[i]
- if test.err != nil {
- test.err = &NumError{"ParseInt", test.in, test.err}
- }
- }
- for i := range parseUint32Tests {
- test := &parseUint32Tests[i]
- if test.err != nil {
- test.err = &NumError{"ParseUint", test.in, test.err}
- }
- }
- for i := range parseInt32Tests {
- test := &parseInt32Tests[i]
- if test.err != nil {
- test.err = &NumError{"ParseInt", test.in, test.err}
- }
- }
-}
-
-func TestParseUint32(t *testing.T) {
- for i := range parseUint32Tests {
- test := &parseUint32Tests[i]
- out, err := ParseUint(test.in, 10, 32)
- if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseUint(%q, 10, 32) = %v, %v want %v, %v",
- test.in, out, err, test.out, test.err)
- }
- }
-}
-
-func TestParseUint64(t *testing.T) {
- for i := range parseUint64Tests {
- test := &parseUint64Tests[i]
- out, err := ParseUint(test.in, 10, 64)
- if test.out != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseUint(%q, 10, 64) = %v, %v want %v, %v",
- test.in, out, err, test.out, test.err)
- }
- }
-}
-
-func TestParseUint64Base(t *testing.T) {
- for i := range parseUint64BaseTests {
- test := &parseUint64BaseTests[i]
- out, err := ParseUint(test.in, test.base, 64)
- if test.out != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseUint(%q, %v, 64) = %v, %v want %v, %v",
- test.in, test.base, out, err, test.out, test.err)
- }
- }
-}
-
-func TestParseInt32(t *testing.T) {
- for i := range parseInt32Tests {
- test := &parseInt32Tests[i]
- out, err := ParseInt(test.in, 10, 32)
- if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseInt(%q, 10 ,32) = %v, %v want %v, %v",
- test.in, out, err, test.out, test.err)
- }
- }
-}
-
-func TestParseInt64(t *testing.T) {
- for i := range parseInt64Tests {
- test := &parseInt64Tests[i]
- out, err := ParseInt(test.in, 10, 64)
- if test.out != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseInt(%q, 10, 64) = %v, %v want %v, %v",
- test.in, out, err, test.out, test.err)
- }
- }
-}
-
-func TestParseInt64Base(t *testing.T) {
- for i := range parseInt64BaseTests {
- test := &parseInt64BaseTests[i]
- out, err := ParseInt(test.in, test.base, 64)
- if test.out != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseInt(%q, %v, 64) = %v, %v want %v, %v",
- test.in, test.base, out, err, test.out, test.err)
- }
- }
-}
-
-func TestParseUint(t *testing.T) {
- switch IntSize {
- case 32:
- for i := range parseUint32Tests {
- test := &parseUint32Tests[i]
- out, err := ParseUint(test.in, 10, 0)
- if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
- test.in, out, err, test.out, test.err)
- }
- }
- case 64:
- for i := range parseUint64Tests {
- test := &parseUint64Tests[i]
- out, err := ParseUint(test.in, 10, 0)
- if test.out != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
- test.in, out, err, test.out, test.err)
- }
- }
- }
-}
-
-func TestParseInt(t *testing.T) {
- switch IntSize {
- case 32:
- for i := range parseInt32Tests {
- test := &parseInt32Tests[i]
- out, err := ParseInt(test.in, 10, 0)
- if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
- test.in, out, err, test.out, test.err)
- }
- }
- case 64:
- for i := range parseInt64Tests {
- test := &parseInt64Tests[i]
- out, err := ParseInt(test.in, 10, 0)
- if test.out != out || !reflect.DeepEqual(test.err, err) {
- t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
- test.in, out, err, test.out, test.err)
- }
- }
- }
-}
-
-func TestAtoi(t *testing.T) {
- switch IntSize {
- case 32:
- for i := range parseInt32Tests {
- test := &parseInt32Tests[i]
- out, err := Atoi(test.in)
- var testErr error
- if test.err != nil {
- testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
- }
- if int(test.out) != out || !reflect.DeepEqual(testErr, err) {
- t.Errorf("Atoi(%q) = %v, %v want %v, %v",
- test.in, out, err, test.out, testErr)
- }
- }
- case 64:
- for i := range parseInt64Tests {
- test := &parseInt64Tests[i]
- out, err := Atoi(test.in)
- var testErr error
- if test.err != nil {
- testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
- }
- if test.out != int64(out) || !reflect.DeepEqual(testErr, err) {
- t.Errorf("Atoi(%q) = %v, %v want %v, %v",
- test.in, out, err, test.out, testErr)
- }
- }
- }
-}
-
-func bitSizeErrStub(name string, bitSize int) error {
- return bitSizeError(name, "0", bitSize)
-}
-
-func baseErrStub(name string, base int) error {
- return baseError(name, "0", base)
-}
-
-func noErrStub(name string, arg int) error {
- return nil
-}
-
-type parseErrorTest struct {
- arg int
- errStub func(name string, arg int) error
-}
-
-var parseBitSizeTests = []parseErrorTest{
- {-1, bitSizeErrStub},
- {0, noErrStub},
- {64, noErrStub},
- {65, bitSizeErrStub},
-}
-
-var parseBaseTests = []parseErrorTest{
- {-1, baseErrStub},
- {0, noErrStub},
- {1, baseErrStub},
- {2, noErrStub},
- {36, noErrStub},
- {37, baseErrStub},
-}
-
-func equalError(a, b error) bool {
- if a == nil {
- return b == nil
- }
- if b == nil {
- return a == nil
- }
- return a.Error() == b.Error()
-}
-
-func TestParseIntBitSize(t *testing.T) {
- for i := range parseBitSizeTests {
- test := &parseBitSizeTests[i]
- testErr := test.errStub("ParseInt", test.arg)
- _, err := ParseInt("0", 0, test.arg)
- if !equalError(testErr, err) {
- t.Errorf("ParseInt(\"0\", 0, %v) = 0, %v want 0, %v",
- test.arg, err, testErr)
- }
- }
-}
-
-func TestParseUintBitSize(t *testing.T) {
- for i := range parseBitSizeTests {
- test := &parseBitSizeTests[i]
- testErr := test.errStub("ParseUint", test.arg)
- _, err := ParseUint("0", 0, test.arg)
- if !equalError(testErr, err) {
- t.Errorf("ParseUint(\"0\", 0, %v) = 0, %v want 0, %v",
- test.arg, err, testErr)
- }
- }
-}
-
-func TestParseIntBase(t *testing.T) {
- for i := range parseBaseTests {
- test := &parseBaseTests[i]
- testErr := test.errStub("ParseInt", test.arg)
- _, err := ParseInt("0", test.arg, 0)
- if !equalError(testErr, err) {
- t.Errorf("ParseInt(\"0\", %v, 0) = 0, %v want 0, %v",
- test.arg, err, testErr)
- }
- }
-}
-
-func TestParseUintBase(t *testing.T) {
- for i := range parseBaseTests {
- test := &parseBaseTests[i]
- testErr := test.errStub("ParseUint", test.arg)
- _, err := ParseUint("0", test.arg, 0)
- if !equalError(testErr, err) {
- t.Errorf("ParseUint(\"0\", %v, 0) = 0, %v want 0, %v",
- test.arg, err, testErr)
- }
- }
-}
-
-func TestNumError(t *testing.T) {
- for _, test := range numErrorTests {
- err := &NumError{
- Func: "ParseFloat",
- Num: test.num,
- Err: errors.New("failed"),
- }
- if got := err.Error(); got != test.want {
- t.Errorf(`(&NumError{"ParseFloat", %q, "failed"}).Error() = %v, want %v`, test.num, got, test.want)
- }
- }
-}
-
-func TestNumErrorUnwrap(t *testing.T) {
- err := &NumError{Err: ErrSyntax}
- if !errors.Is(err, ErrSyntax) {
- t.Error("errors.Is failed, wanted success")
- }
-}
-
-func BenchmarkParseInt(b *testing.B) {
- b.Run("Pos", func(b *testing.B) {
- benchmarkParseInt(b, 1)
- })
- b.Run("Neg", func(b *testing.B) {
- benchmarkParseInt(b, -1)
- })
-}
-
-type benchCase struct {
- name string
- num int64
-}
-
-func benchmarkParseInt(b *testing.B, neg int) {
- cases := []benchCase{
- {"7bit", 1<<7 - 1},
- {"26bit", 1<<26 - 1},
- {"31bit", 1<<31 - 1},
- {"56bit", 1<<56 - 1},
- {"63bit", 1<<63 - 1},
- }
- for _, cs := range cases {
- b.Run(cs.name, func(b *testing.B) {
- s := fmt.Sprintf("%d", cs.num*int64(neg))
- for i := 0; i < b.N; i++ {
- out, _ := ParseInt(s, 10, 64)
- BenchSink += int(out)
- }
- })
- }
-}
-
-func BenchmarkAtoi(b *testing.B) {
- b.Run("Pos", func(b *testing.B) {
- benchmarkAtoi(b, 1)
- })
- b.Run("Neg", func(b *testing.B) {
- benchmarkAtoi(b, -1)
- })
-}
-
-func benchmarkAtoi(b *testing.B, neg int) {
- cases := []benchCase{
- {"7bit", 1<<7 - 1},
- {"26bit", 1<<26 - 1},
- {"31bit", 1<<31 - 1},
- }
- if IntSize == 64 {
- cases = append(cases, []benchCase{
- {"56bit", 1<<56 - 1},
- {"63bit", 1<<63 - 1},
- }...)
- }
- for _, cs := range cases {
- b.Run(cs.name, func(b *testing.B) {
- s := fmt.Sprintf("%d", cs.num*int64(neg))
- for i := 0; i < b.N; i++ {
- out, _ := Atoi(s)
- BenchSink += out
- }
- })
- }
-}
diff --git a/src/strconv/ctoa.go b/src/strconv/ctoa.go
deleted file mode 100644
index fd7f941d70..0000000000
--- a/src/strconv/ctoa.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2020 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
-
-// FormatComplex converts the complex number c to a string of the
-// form (a+bi) where a and b are the real and imaginary parts,
-// formatted according to the format fmt and precision prec.
-//
-// The format fmt and precision prec have the same meaning as in [FormatFloat].
-// It rounds the result assuming that the original was obtained from a complex
-// value of bitSize bits, which must be 64 for complex64 and 128 for complex128.
-func FormatComplex(c complex128, fmt byte, prec, bitSize int) string {
- if bitSize != 64 && bitSize != 128 {
- panic("invalid bitSize")
- }
- bitSize >>= 1 // complex64 uses float32 internally
-
- // Check if imaginary part has a sign. If not, add one.
- im := FormatFloat(imag(c), fmt, prec, bitSize)
- if im[0] != '+' && im[0] != '-' {
- im = "+" + im
- }
-
- return "(" + FormatFloat(real(c), fmt, prec, bitSize) + im + "i)"
-}
diff --git a/src/strconv/ctoa_test.go b/src/strconv/ctoa_test.go
deleted file mode 100644
index 8b77898ecc..0000000000
--- a/src/strconv/ctoa_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2020 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 (
- . "strconv"
- "testing"
-)
-
-func TestFormatComplex(t *testing.T) {
- tests := []struct {
- c complex128
- fmt byte
- prec int
- bitSize int
- out string
- }{
- // a variety of signs
- {1 + 2i, 'g', -1, 128, "(1+2i)"},
- {3 - 4i, 'g', -1, 128, "(3-4i)"},
- {-5 + 6i, 'g', -1, 128, "(-5+6i)"},
- {-7 - 8i, 'g', -1, 128, "(-7-8i)"},
-
- // test that fmt and prec are working
- {3.14159 + 0.00123i, 'e', 3, 128, "(3.142e+00+1.230e-03i)"},
- {3.14159 + 0.00123i, 'f', 3, 128, "(3.142+0.001i)"},
- {3.14159 + 0.00123i, 'g', 3, 128, "(3.14+0.00123i)"},
-
- // ensure bitSize rounding is working
- {1.2345678901234567 + 9.876543210987654i, 'f', -1, 128, "(1.2345678901234567+9.876543210987654i)"},
- {1.2345678901234567 + 9.876543210987654i, 'f', -1, 64, "(1.2345679+9.876543i)"},
-
- // other cases are handled by FormatFloat tests
- }
- for _, test := range tests {
- out := FormatComplex(test.c, test.fmt, test.prec, test.bitSize)
- if out != test.out {
- t.Fatalf("FormatComplex(%v, %q, %d, %d) = %q; want %q",
- test.c, test.fmt, test.prec, test.bitSize, out, test.out)
- }
- }
-}
-
-func TestFormatComplexInvalidBitSize(t *testing.T) {
- defer func() {
- if r := recover(); r == nil {
- t.Fatalf("expected panic due to invalid bitSize")
- }
- }()
- _ = FormatComplex(1+2i, 'g', -1, 100)
-}
diff --git a/src/strconv/decimal.go b/src/strconv/decimal.go
deleted file mode 100644
index b58001888e..0000000000
--- a/src/strconv/decimal.go
+++ /dev/null
@@ -1,415 +0,0 @@
-// 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.
-
-// Multiprecision decimal numbers.
-// For floating-point formatting only; not general purpose.
-// Only operations are assign and (binary) left/right shift.
-// Can do binary floating point in multiprecision decimal precisely
-// because 2 divides 10; cannot do decimal floating point
-// in multiprecision binary precisely.
-
-package strconv
-
-type decimal struct {
- d [800]byte // digits, big-endian representation
- nd int // number of digits used
- dp int // decimal point
- neg bool // negative flag
- trunc bool // discarded nonzero digits beyond d[:nd]
-}
-
-func (a *decimal) String() string {
- n := 10 + a.nd
- if a.dp > 0 {
- n += a.dp
- }
- if a.dp < 0 {
- n += -a.dp
- }
-
- buf := make([]byte, n)
- w := 0
- switch {
- case a.nd == 0:
- return "0"
-
- case a.dp <= 0:
- // zeros fill space between decimal point and digits
- buf[w] = '0'
- w++
- buf[w] = '.'
- w++
- w += digitZero(buf[w : w+-a.dp])
- w += copy(buf[w:], a.d[0:a.nd])
-
- case a.dp < a.nd:
- // decimal point in middle of digits
- w += copy(buf[w:], a.d[0:a.dp])
- buf[w] = '.'
- w++
- w += copy(buf[w:], a.d[a.dp:a.nd])
-
- default:
- // zeros fill space between digits and decimal point
- w += copy(buf[w:], a.d[0:a.nd])
- w += digitZero(buf[w : w+a.dp-a.nd])
- }
- return string(buf[0:w])
-}
-
-func digitZero(dst []byte) int {
- for i := range dst {
- dst[i] = '0'
- }
- return len(dst)
-}
-
-// trim trailing zeros from number.
-// (They are meaningless; the decimal point is tracked
-// independent of the number of digits.)
-func trim(a *decimal) {
- for a.nd > 0 && a.d[a.nd-1] == '0' {
- a.nd--
- }
- if a.nd == 0 {
- a.dp = 0
- }
-}
-
-// Assign v to a.
-func (a *decimal) Assign(v uint64) {
- var buf [24]byte
-
- // Write reversed decimal in buf.
- n := 0
- for v > 0 {
- v1 := v / 10
- v -= 10 * v1
- buf[n] = byte(v + '0')
- n++
- v = v1
- }
-
- // Reverse again to produce forward decimal in a.d.
- a.nd = 0
- for n--; n >= 0; n-- {
- a.d[a.nd] = buf[n]
- a.nd++
- }
- a.dp = a.nd
- trim(a)
-}
-
-// Maximum shift that we can do in one pass without overflow.
-// A uint has 32 or 64 bits, and we have to be able to accommodate 9<<k.
-const uintSize = 32 << (^uint(0) >> 63)
-const maxShift = uintSize - 4
-
-// Binary shift right (/ 2) by k bits. k <= maxShift to avoid overflow.
-func rightShift(a *decimal, k uint) {
- r := 0 // read pointer
- w := 0 // write pointer
-
- // Pick up enough leading digits to cover first shift.
- var n uint
- for ; n>>k == 0; r++ {
- if r >= a.nd {
- if n == 0 {
- // a == 0; shouldn't get here, but handle anyway.
- a.nd = 0
- return
- }
- for n>>k == 0 {
- n = n * 10
- r++
- }
- break
- }
- c := uint(a.d[r])
- n = n*10 + c - '0'
- }
- a.dp -= r - 1
-
- var mask uint = (1 << k) - 1
-
- // Pick up a digit, put down a digit.
- for ; r < a.nd; r++ {
- c := uint(a.d[r])
- dig := n >> k
- n &= mask
- a.d[w] = byte(dig + '0')
- w++
- n = n*10 + c - '0'
- }
-
- // Put down extra digits.
- for n > 0 {
- dig := n >> k
- n &= mask
- if w < len(a.d) {
- a.d[w] = byte(dig + '0')
- w++
- } else if dig > 0 {
- a.trunc = true
- }
- n = n * 10
- }
-
- a.nd = w
- trim(a)
-}
-
-// Cheat sheet for left shift: table indexed by shift count giving
-// number of new digits that will be introduced by that shift.
-//
-// For example, leftcheats[4] = {2, "625"}. That means that
-// if we are shifting by 4 (multiplying by 16), it will add 2 digits
-// when the string prefix is "625" through "999", and one fewer digit
-// if the string prefix is "000" through "624".
-//
-// Credit for this trick goes to Ken.
-
-type leftCheat struct {
- delta int // number of new digits
- cutoff string // minus one digit if original < a.
-}
-
-var leftcheats = []leftCheat{
- // Leading digits of 1/2^i = 5^i.
- // 5^23 is not an exact 64-bit floating point number,
- // so have to use bc for the math.
- // Go up to 60 to be large enough for 32bit and 64bit platforms.
- /*
- seq 60 | sed 's/^/5^/' | bc |
- awk 'BEGIN{ print "\t{ 0, \"\" }," }
- {
- log2 = log(2)/log(10)
- printf("\t{ %d, \"%s\" },\t// * %d\n",
- int(log2*NR+1), $0, 2**NR)
- }'
- */
- {0, ""},
- {1, "5"}, // * 2
- {1, "25"}, // * 4
- {1, "125"}, // * 8
- {2, "625"}, // * 16
- {2, "3125"}, // * 32
- {2, "15625"}, // * 64
- {3, "78125"}, // * 128
- {3, "390625"}, // * 256
- {3, "1953125"}, // * 512
- {4, "9765625"}, // * 1024
- {4, "48828125"}, // * 2048
- {4, "244140625"}, // * 4096
- {4, "1220703125"}, // * 8192
- {5, "6103515625"}, // * 16384
- {5, "30517578125"}, // * 32768
- {5, "152587890625"}, // * 65536
- {6, "762939453125"}, // * 131072
- {6, "3814697265625"}, // * 262144
- {6, "19073486328125"}, // * 524288
- {7, "95367431640625"}, // * 1048576
- {7, "476837158203125"}, // * 2097152
- {7, "2384185791015625"}, // * 4194304
- {7, "11920928955078125"}, // * 8388608
- {8, "59604644775390625"}, // * 16777216
- {8, "298023223876953125"}, // * 33554432
- {8, "1490116119384765625"}, // * 67108864
- {9, "7450580596923828125"}, // * 134217728
- {9, "37252902984619140625"}, // * 268435456
- {9, "186264514923095703125"}, // * 536870912
- {10, "931322574615478515625"}, // * 1073741824
- {10, "4656612873077392578125"}, // * 2147483648
- {10, "23283064365386962890625"}, // * 4294967296
- {10, "116415321826934814453125"}, // * 8589934592
- {11, "582076609134674072265625"}, // * 17179869184
- {11, "2910383045673370361328125"}, // * 34359738368
- {11, "14551915228366851806640625"}, // * 68719476736
- {12, "72759576141834259033203125"}, // * 137438953472
- {12, "363797880709171295166015625"}, // * 274877906944
- {12, "1818989403545856475830078125"}, // * 549755813888
- {13, "9094947017729282379150390625"}, // * 1099511627776
- {13, "45474735088646411895751953125"}, // * 2199023255552
- {13, "227373675443232059478759765625"}, // * 4398046511104
- {13, "1136868377216160297393798828125"}, // * 8796093022208
- {14, "5684341886080801486968994140625"}, // * 17592186044416
- {14, "28421709430404007434844970703125"}, // * 35184372088832
- {14, "142108547152020037174224853515625"}, // * 70368744177664
- {15, "710542735760100185871124267578125"}, // * 140737488355328
- {15, "3552713678800500929355621337890625"}, // * 281474976710656
- {15, "17763568394002504646778106689453125"}, // * 562949953421312
- {16, "88817841970012523233890533447265625"}, // * 1125899906842624
- {16, "444089209850062616169452667236328125"}, // * 2251799813685248
- {16, "2220446049250313080847263336181640625"}, // * 4503599627370496
- {16, "11102230246251565404236316680908203125"}, // * 9007199254740992
- {17, "55511151231257827021181583404541015625"}, // * 18014398509481984
- {17, "277555756156289135105907917022705078125"}, // * 36028797018963968
- {17, "1387778780781445675529539585113525390625"}, // * 72057594037927936
- {18, "6938893903907228377647697925567626953125"}, // * 144115188075855872
- {18, "34694469519536141888238489627838134765625"}, // * 288230376151711744
- {18, "173472347597680709441192448139190673828125"}, // * 576460752303423488
- {19, "867361737988403547205962240695953369140625"}, // * 1152921504606846976
-}
-
-// Is the leading prefix of b lexicographically less than s?
-func prefixIsLessThan(b []byte, s string) bool {
- for i := 0; i < len(s); i++ {
- if i >= len(b) {
- return true
- }
- if b[i] != s[i] {
- return b[i] < s[i]
- }
- }
- return false
-}
-
-// Binary shift left (* 2) by k bits. k <= maxShift to avoid overflow.
-func leftShift(a *decimal, k uint) {
- delta := leftcheats[k].delta
- if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
- delta--
- }
-
- r := a.nd // read index
- w := a.nd + delta // write index
-
- // Pick up a digit, put down a digit.
- var n uint
- for r--; r >= 0; r-- {
- n += (uint(a.d[r]) - '0') << k
- quo := n / 10
- rem := n - 10*quo
- w--
- if w < len(a.d) {
- a.d[w] = byte(rem + '0')
- } else if rem != 0 {
- a.trunc = true
- }
- n = quo
- }
-
- // Put down extra digits.
- for n > 0 {
- quo := n / 10
- rem := n - 10*quo
- w--
- if w < len(a.d) {
- a.d[w] = byte(rem + '0')
- } else if rem != 0 {
- a.trunc = true
- }
- n = quo
- }
-
- a.nd += delta
- if a.nd >= len(a.d) {
- a.nd = len(a.d)
- }
- a.dp += delta
- trim(a)
-}
-
-// Binary shift left (k > 0) or right (k < 0).
-func (a *decimal) Shift(k int) {
- switch {
- case a.nd == 0:
- // nothing to do: a == 0
- case k > 0:
- for k > maxShift {
- leftShift(a, maxShift)
- k -= maxShift
- }
- leftShift(a, uint(k))
- case k < 0:
- for k < -maxShift {
- rightShift(a, maxShift)
- k += maxShift
- }
- rightShift(a, uint(-k))
- }
-}
-
-// If we chop a at nd digits, should we round up?
-func shouldRoundUp(a *decimal, nd int) bool {
- if nd < 0 || nd >= a.nd {
- return false
- }
- if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even
- // if we truncated, a little higher than what's recorded - always round up
- if a.trunc {
- return true
- }
- return nd > 0 && (a.d[nd-1]-'0')%2 != 0
- }
- // not halfway - digit tells all
- return a.d[nd] >= '5'
-}
-
-// Round a to nd digits (or fewer).
-// If nd is zero, it means we're rounding
-// just to the left of the digits, as in
-// 0.09 -> 0.1.
-func (a *decimal) Round(nd int) {
- if nd < 0 || nd >= a.nd {
- return
- }
- if shouldRoundUp(a, nd) {
- a.RoundUp(nd)
- } else {
- a.RoundDown(nd)
- }
-}
-
-// Round a down to nd digits (or fewer).
-func (a *decimal) RoundDown(nd int) {
- if nd < 0 || nd >= a.nd {
- return
- }
- a.nd = nd
- trim(a)
-}
-
-// Round a up to nd digits (or fewer).
-func (a *decimal) RoundUp(nd int) {
- if nd < 0 || nd >= a.nd {
- return
- }
-
- // round up
- for i := nd - 1; i >= 0; i-- {
- c := a.d[i]
- if c < '9' { // can stop after this digit
- a.d[i]++
- a.nd = i + 1
- return
- }
- }
-
- // Number is all 9s.
- // Change to single 1 with adjusted decimal point.
- a.d[0] = '1'
- a.nd = 1
- a.dp++
-}
-
-// Extract integer part, rounded appropriately.
-// No guarantees about overflow.
-func (a *decimal) RoundedInteger() uint64 {
- if a.dp > 20 {
- return 0xFFFFFFFFFFFFFFFF
- }
- var i int
- n := uint64(0)
- for i = 0; i < a.dp && i < a.nd; i++ {
- n = n*10 + uint64(a.d[i]-'0')
- }
- for ; i < a.dp; i++ {
- n *= 10
- }
- if shouldRoundUp(a, a.dp) {
- n++
- }
- return n
-}
diff --git a/src/strconv/decimal_test.go b/src/strconv/decimal_test.go
deleted file mode 100644
index 13a127f5b2..0000000000
--- a/src/strconv/decimal_test.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// 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 (
- . "strconv"
- "testing"
-)
-
-type shiftTest struct {
- i uint64
- shift int
- out string
-}
-
-var shifttests = []shiftTest{
- {0, -100, "0"},
- {0, 100, "0"},
- {1, 100, "1267650600228229401496703205376"},
- {1, -100,
- "0.00000000000000000000000000000078886090522101180541" +
- "17285652827862296732064351090230047702789306640625",
- },
- {12345678, 8, "3160493568"},
- {12345678, -8, "48225.3046875"},
- {195312, 9, "99999744"},
- {1953125, 9, "1000000000"},
-}
-
-func TestDecimalShift(t *testing.T) {
- for i := 0; i < len(shifttests); i++ {
- test := &shifttests[i]
- d := NewDecimal(test.i)
- d.Shift(test.shift)
- s := d.String()
- if s != test.out {
- t.Errorf("Decimal %v << %v = %v, want %v",
- test.i, test.shift, s, test.out)
- }
- }
-}
-
-type roundTest struct {
- i uint64
- nd int
- down, round, up string
- int uint64
-}
-
-var roundtests = []roundTest{
- {0, 4, "0", "0", "0", 0},
- {12344999, 4, "12340000", "12340000", "12350000", 12340000},
- {12345000, 4, "12340000", "12340000", "12350000", 12340000},
- {12345001, 4, "12340000", "12350000", "12350000", 12350000},
- {23454999, 4, "23450000", "23450000", "23460000", 23450000},
- {23455000, 4, "23450000", "23460000", "23460000", 23460000},
- {23455001, 4, "23450000", "23460000", "23460000", 23460000},
-
- {99994999, 4, "99990000", "99990000", "100000000", 99990000},
- {99995000, 4, "99990000", "100000000", "100000000", 100000000},
- {99999999, 4, "99990000", "100000000", "100000000", 100000000},
-
- {12994999, 4, "12990000", "12990000", "13000000", 12990000},
- {12995000, 4, "12990000", "13000000", "13000000", 13000000},
- {12999999, 4, "12990000", "13000000", "13000000", 13000000},
-}
-
-func TestDecimalRound(t *testing.T) {
- for i := 0; i < len(roundtests); i++ {
- test := &roundtests[i]
- d := NewDecimal(test.i)
- d.RoundDown(test.nd)
- s := d.String()
- if s != test.down {
- t.Errorf("Decimal %v RoundDown %d = %v, want %v",
- test.i, test.nd, s, test.down)
- }
- d = NewDecimal(test.i)
- d.Round(test.nd)
- s = d.String()
- if s != test.round {
- t.Errorf("Decimal %v Round %d = %v, want %v",
- test.i, test.nd, s, test.down)
- }
- d = NewDecimal(test.i)
- d.RoundUp(test.nd)
- s = d.String()
- if s != test.up {
- t.Errorf("Decimal %v RoundUp %d = %v, want %v",
- test.i, test.nd, s, test.up)
- }
- }
-}
-
-type roundIntTest struct {
- i uint64
- shift int
- int uint64
-}
-
-var roundinttests = []roundIntTest{
- {0, 100, 0},
- {512, -8, 2},
- {513, -8, 2},
- {640, -8, 2},
- {641, -8, 3},
- {384, -8, 2},
- {385, -8, 2},
- {383, -8, 1},
- {1, 100, 1<<64 - 1},
- {1000, 0, 1000},
-}
-
-func TestDecimalRoundedInteger(t *testing.T) {
- for i := 0; i < len(roundinttests); i++ {
- test := roundinttests[i]
- d := NewDecimal(test.i)
- d.Shift(test.shift)
- int := d.RoundedInteger()
- if int != test.int {
- t.Errorf("Decimal %v >> %v RoundedInteger = %v, want %v",
- test.i, test.shift, int, test.int)
- }
- }
-}
diff --git a/src/strconv/eisel_lemire.go b/src/strconv/eisel_lemire.go
deleted file mode 100644
index 7bc9c71a40..0000000000
--- a/src/strconv/eisel_lemire.go
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2020 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
-
-// This file implements the Eisel-Lemire ParseFloat algorithm, published in
-// 2020 and discussed extensively at
-// https://nigeltao.github.io/blog/2020/eisel-lemire.html
-//
-// The original C++ implementation is at
-// https://github.com/lemire/fast_double_parser/blob/644bef4306059d3be01a04e77d3cc84b379c596f/include/fast_double_parser.h#L840
-//
-// This Go re-implementation closely follows the C re-implementation at
-// https://github.com/google/wuffs/blob/ba3818cb6b473a2ed0b38ecfc07dbbd3a97e8ae7/internal/cgen/base/floatconv-submodule-code.c#L990
-//
-// Additional testing (on over several million test strings) is done by
-// https://github.com/nigeltao/parse-number-fxx-test-data/blob/5280dcfccf6d0b02a65ae282dad0b6d9de50e039/script/test-go-strconv.go
-
-import (
- "math"
- "math/bits"
-)
-
-func eiselLemire64(man uint64, exp10 int, neg bool) (f float64, ok bool) {
- // The terse comments in this function body refer to sections of the
- // https://nigeltao.github.io/blog/2020/eisel-lemire.html blog post.
-
- // Exp10 Range.
- if man == 0 {
- if neg {
- f = math.Float64frombits(0x8000000000000000) // Negative zero.
- }
- return f, true
- }
- pow, exp2, ok := pow10(exp10)
- if !ok {
- return 0, false
- }
-
- // Normalization.
- clz := bits.LeadingZeros64(man)
- man <<= uint(clz)
- retExp2 := uint64(exp2+64-float64Bias) - uint64(clz)
-
- // Multiplication.
- xHi, xLo := bits.Mul64(man, pow.Hi)
-
- // Wider Approximation.
- if xHi&0x1FF == 0x1FF && xLo+man < man {
- yHi, yLo := bits.Mul64(man, pow.Lo)
- mergedHi, mergedLo := xHi, xLo+yHi
- if mergedLo < xLo {
- mergedHi++
- }
- if mergedHi&0x1FF == 0x1FF && mergedLo+1 == 0 && yLo+man < man {
- return 0, false
- }
- xHi, xLo = mergedHi, mergedLo
- }
-
- // Shifting to 54 Bits.
- msb := xHi >> 63
- retMantissa := xHi >> (msb + 9)
- retExp2 -= 1 ^ msb
-
- // Half-way Ambiguity.
- if xLo == 0 && xHi&0x1FF == 0 && retMantissa&3 == 1 {
- return 0, false
- }
-
- // From 54 to 53 Bits.
- retMantissa += retMantissa & 1
- retMantissa >>= 1
- if retMantissa>>53 > 0 {
- retMantissa >>= 1
- retExp2 += 1
- }
- // retExp2 is a uint64. Zero or underflow means that we're in subnormal
- // float64 space. 0x7FF or above means that we're in Inf/NaN float64 space.
- //
- // The if block is equivalent to (but has fewer branches than):
- // if retExp2 <= 0 || retExp2 >= 0x7FF { etc }
- if retExp2-1 >= 0x7FF-1 {
- return 0, false
- }
- retBits := retExp2<<float64MantBits | retMantissa&(1<<float64MantBits-1)
- if neg {
- retBits |= 0x8000000000000000
- }
- return math.Float64frombits(retBits), true
-}
-
-func eiselLemire32(man uint64, exp10 int, neg bool) (f float32, ok bool) {
- // The terse comments in this function body refer to sections of the
- // https://nigeltao.github.io/blog/2020/eisel-lemire.html blog post.
- //
- // That blog post discusses the float64 flavor (11 exponent bits with a
- // -1023 bias, 52 mantissa bits) of the algorithm, but the same approach
- // applies to the float32 flavor (8 exponent bits with a -127 bias, 23
- // mantissa bits). The computation here happens with 64-bit values (e.g.
- // man, xHi, retMantissa) before finally converting to a 32-bit float.
-
- // Exp10 Range.
- if man == 0 {
- if neg {
- f = math.Float32frombits(0x80000000) // Negative zero.
- }
- return f, true
- }
- pow, exp2, ok := pow10(exp10)
- if !ok {
- return 0, false
- }
-
- // Normalization.
- clz := bits.LeadingZeros64(man)
- man <<= uint(clz)
- retExp2 := uint64(exp2+64-float32Bias) - uint64(clz)
-
- // Multiplication.
- xHi, xLo := bits.Mul64(man, pow.Hi)
-
- // Wider Approximation.
- if xHi&0x3FFFFFFFFF == 0x3FFFFFFFFF && xLo+man < man {
- yHi, yLo := bits.Mul64(man, pow.Lo)
- mergedHi, mergedLo := xHi, xLo+yHi
- if mergedLo < xLo {
- mergedHi++
- }
- if mergedHi&0x3FFFFFFFFF == 0x3FFFFFFFFF && mergedLo+1 == 0 && yLo+man < man {
- return 0, false
- }
- xHi, xLo = mergedHi, mergedLo
- }
-
- // Shifting to 54 Bits (and for float32, it's shifting to 25 bits).
- msb := xHi >> 63
- retMantissa := xHi >> (msb + 38)
- retExp2 -= 1 ^ msb
-
- // Half-way Ambiguity.
- if xLo == 0 && xHi&0x3FFFFFFFFF == 0 && retMantissa&3 == 1 {
- return 0, false
- }
-
- // From 54 to 53 Bits (and for float32, it's from 25 to 24 bits).
- retMantissa += retMantissa & 1
- retMantissa >>= 1
- if retMantissa>>24 > 0 {
- retMantissa >>= 1
- retExp2 += 1
- }
- // retExp2 is a uint64. Zero or underflow means that we're in subnormal
- // float32 space. 0xFF or above means that we're in Inf/NaN float32 space.
- //
- // The if block is equivalent to (but has fewer branches than):
- // if retExp2 <= 0 || retExp2 >= 0xFF { etc }
- if retExp2-1 >= 0xFF-1 {
- return 0, false
- }
- retBits := retExp2<<float32MantBits | retMantissa&(1<<float32MantBits-1)
- if neg {
- retBits |= 0x80000000
- }
- return math.Float32frombits(uint32(retBits)), true
-}
diff --git a/src/strconv/export_test.go b/src/strconv/export_test.go
index 3518bb233c..7a3c761e68 100644
--- a/src/strconv/export_test.go
+++ b/src/strconv/export_test.go
@@ -4,27 +4,7 @@
package strconv
-type Uint128 = uint128
-
var (
- BaseError = baseError
- BitSizeError = bitSizeError
- MulLog10_2 = mulLog10_2
- MulLog2_10 = mulLog2_10
- ParseFloatPrefix = parseFloatPrefix
- Pow10 = pow10
- Umul128 = umul128
- Umul192 = umul192
+ BaseError = baseError
+ BitSizeError = bitSizeError
)
-
-func NewDecimal(i uint64) *decimal {
- d := new(decimal)
- d.Assign(i)
- return d
-}
-
-func SetOptimize(b bool) bool {
- old := optimize
- optimize = b
- return old
-}
diff --git a/src/strconv/fp_test.go b/src/strconv/fp_test.go
deleted file mode 100644
index 376e8f591c..0000000000
--- a/src/strconv/fp_test.go
+++ /dev/null
@@ -1,138 +0,0 @@
-// 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 (
- "bufio"
- _ "embed"
- "fmt"
- "strconv"
- "strings"
- "testing"
-)
-
-func pow2(i int) float64 {
- switch {
- case i < 0:
- return 1 / pow2(-i)
- case i == 0:
- return 1
- case i == 1:
- return 2
- }
- return pow2(i/2) * pow2(i-i/2)
-}
-
-// Wrapper around strconv.ParseFloat(x, 64). Handles dddddp+ddd (binary exponent)
-// itself, passes the rest on to strconv.ParseFloat.
-func myatof64(s string) (f float64, ok bool) {
- if mant, exp, ok := strings.Cut(s, "p"); ok {
- n, err := strconv.ParseInt(mant, 10, 64)
- if err != nil {
- return 0, false
- }
- e, err1 := strconv.Atoi(exp)
- if err1 != nil {
- println("bad e", exp)
- return 0, false
- }
- v := float64(n)
- // We expect that v*pow2(e) fits in a float64,
- // but pow2(e) by itself may not. Be careful.
- if e <= -1000 {
- v *= pow2(-1000)
- e += 1000
- for e < 0 {
- v /= 2
- e++
- }
- return v, true
- }
- if e >= 1000 {
- v *= pow2(1000)
- e -= 1000
- for e > 0 {
- v *= 2
- e--
- }
- return v, true
- }
- return v * pow2(e), true
- }
- f1, err := strconv.ParseFloat(s, 64)
- if err != nil {
- return 0, false
- }
- return f1, true
-}
-
-// Wrapper around strconv.ParseFloat(x, 32). Handles dddddp+ddd (binary exponent)
-// itself, passes the rest on to strconv.ParseFloat.
-func myatof32(s string) (f float32, ok bool) {
- if mant, exp, ok := strings.Cut(s, "p"); ok {
- n, err := strconv.Atoi(mant)
- if err != nil {
- println("bad n", mant)
- return 0, false
- }
- e, err1 := strconv.Atoi(exp)
- if err1 != nil {
- println("bad p", exp)
- return 0, false
- }
- return float32(float64(n) * pow2(e)), true
- }
- f64, err1 := strconv.ParseFloat(s, 32)
- f1 := float32(f64)
- if err1 != nil {
- return 0, false
- }
- return f1, true
-}
-
-//go:embed testdata/testfp.txt
-var testfp string
-
-func TestFp(t *testing.T) {
- s := bufio.NewScanner(strings.NewReader(testfp))
- for lineno := 1; s.Scan(); lineno++ {
- line := s.Text()
- if len(line) == 0 || line[0] == '#' {
- continue
- }
- a := strings.Split(line, " ")
- if len(a) != 4 {
- t.Error("testdata/testfp.txt:", lineno, ": wrong field count")
- continue
- }
- var s string
- var v float64
- switch a[0] {
- case "float64":
- var ok bool
- v, ok = myatof64(a[2])
- if !ok {
- t.Error("testdata/testfp.txt:", lineno, ": cannot atof64 ", a[2])
- continue
- }
- s = fmt.Sprintf(a[1], v)
- case "float32":
- v1, ok := myatof32(a[2])
- if !ok {
- t.Error("testdata/testfp.txt:", lineno, ": cannot atof32 ", a[2])
- continue
- }
- s = fmt.Sprintf(a[1], v1)
- v = float64(v1)
- }
- if s != a[3] {
- t.Error("testdata/testfp.txt:", lineno, ": ", a[0], " ", a[1], " ", a[2], " (", v, ") ",
- "want ", a[3], " got ", s)
- }
- }
- if s.Err() != nil {
- t.Fatal("testfp: read testdata/testfp.txt: ", s.Err())
- }
-}
diff --git a/src/strconv/ftoa.go b/src/strconv/ftoa.go
deleted file mode 100644
index 1d4bf770be..0000000000
--- a/src/strconv/ftoa.go
+++ /dev/null
@@ -1,582 +0,0 @@
-// 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.
-
-// Binary to decimal floating point conversion.
-// Algorithm:
-// 1) store mantissa in multiprecision decimal
-// 2) shift decimal by exponent
-// 3) read digits out & format
-
-package strconv
-
-import "math"
-
-type floatInfo struct {
- mantbits uint
- expbits uint
- bias int
-}
-
-const (
- float32MantBits = 23
- float32ExpBits = 8
- float32Bias = -127
- float64MantBits = 52
- float64ExpBits = 11
- float64Bias = -1023
-)
-
-var (
- float32info = floatInfo{float32MantBits, float32ExpBits, float32Bias}
- float64info = floatInfo{float64MantBits, float64ExpBits, float64Bias}
-)
-
-// FormatFloat converts the floating-point number f to a string,
-// according to the format fmt and precision prec. It rounds the
-// result assuming that the original was obtained from a floating-point
-// value of bitSize bits (32 for float32, 64 for float64).
-//
-// The format fmt is one of
-// - 'b' (-ddddp±ddd, a binary exponent),
-// - 'e' (-d.dddde±dd, a decimal exponent),
-// - 'E' (-d.ddddE±dd, a decimal exponent),
-// - 'f' (-ddd.dddd, no exponent),
-// - 'g' ('e' for large exponents, 'f' otherwise),
-// - 'G' ('E' for large exponents, 'f' otherwise),
-// - 'x' (-0xd.ddddp±ddd, a hexadecimal fraction and binary exponent), or
-// - 'X' (-0Xd.ddddP±ddd, a hexadecimal fraction and binary exponent).
-//
-// The precision prec controls the number of digits (excluding the exponent)
-// printed by the 'e', 'E', 'f', 'g', 'G', 'x', and 'X' formats.
-// For 'e', 'E', 'f', 'x', and 'X', it is the number of digits after the decimal point.
-// For 'g' and 'G' it is the maximum number of significant digits (trailing
-// zeros are removed).
-// The special precision -1 uses the smallest number of digits
-// necessary such that ParseFloat will return f exactly.
-// The exponent is written as a decimal integer;
-// for all formats other than 'b', it will be at least two digits.
-func FormatFloat(f float64, fmt byte, prec, bitSize int) string {
- return string(genericFtoa(make([]byte, 0, max(prec+4, 24)), f, fmt, prec, bitSize))
-}
-
-// AppendFloat appends the string form of the floating-point number f,
-// as generated by [FormatFloat], to dst and returns the extended buffer.
-func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte {
- return genericFtoa(dst, f, fmt, prec, bitSize)
-}
-
-func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte {
- var bits uint64
- var flt *floatInfo
- switch bitSize {
- case 32:
- bits = uint64(math.Float32bits(float32(val)))
- flt = &float32info
- case 64:
- bits = math.Float64bits(val)
- flt = &float64info
- default:
- panic("strconv: illegal AppendFloat/FormatFloat bitSize")
- }
-
- neg := bits>>(flt.expbits+flt.mantbits) != 0
- exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
- mant := bits & (uint64(1)<<flt.mantbits - 1)
-
- switch exp {
- case 1<<flt.expbits - 1:
- // Inf, NaN
- var s string
- switch {
- case mant != 0:
- s = "NaN"
- case neg:
- s = "-Inf"
- default:
- s = "+Inf"
- }
- return append(dst, s...)
-
- case 0:
- // denormalized
- exp++
-
- default:
- // add implicit top bit
- mant |= uint64(1) << flt.mantbits
- }
- exp += flt.bias
-
- // Pick off easy binary, hex formats.
- if fmt == 'b' {
- return fmtB(dst, neg, mant, exp, flt)
- }
- if fmt == 'x' || fmt == 'X' {
- return fmtX(dst, prec, fmt, neg, mant, exp, flt)
- }
-
- if !optimize {
- return bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
- }
-
- var digs decimalSlice
- ok := false
- // Negative precision means "only as much as needed to be exact."
- shortest := prec < 0
- if shortest {
- // Use Ryu algorithm.
- var buf [32]byte
- digs.d = buf[:]
- ryuFtoaShortest(&digs, mant, exp-int(flt.mantbits), flt)
- ok = true
- // Precision for shortest representation mode.
- switch fmt {
- case 'e', 'E':
- prec = max(digs.nd-1, 0)
- case 'f':
- prec = max(digs.nd-digs.dp, 0)
- case 'g', 'G':
- prec = digs.nd
- }
- } else if fmt != 'f' {
- // Fixed number of digits.
- digits := prec
- switch fmt {
- case 'e', 'E':
- digits++
- case 'g', 'G':
- if prec == 0 {
- prec = 1
- }
- digits = prec
- default:
- // Invalid mode.
- digits = 1
- }
- var buf [24]byte
- if bitSize == 32 && digits <= 9 {
- digs.d = buf[:]
- ryuFtoaFixed32(&digs, uint32(mant), exp-int(flt.mantbits), digits)
- ok = true
- } else if digits <= 18 {
- digs.d = buf[:]
- ryuFtoaFixed64(&digs, mant, exp-int(flt.mantbits), digits)
- ok = true
- }
- }
- if !ok {
- return bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
- }
- return formatDigits(dst, shortest, neg, digs, prec, fmt)
-}
-
-// bigFtoa uses multiprecision computations to format a float.
-func bigFtoa(dst []byte, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
- d := new(decimal)
- d.Assign(mant)
- d.Shift(exp - int(flt.mantbits))
- var digs decimalSlice
- shortest := prec < 0
- if shortest {
- roundShortest(d, mant, exp, flt)
- digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
- // Precision for shortest representation mode.
- switch fmt {
- case 'e', 'E':
- prec = digs.nd - 1
- case 'f':
- prec = max(digs.nd-digs.dp, 0)
- case 'g', 'G':
- prec = digs.nd
- }
- } else {
- // Round appropriately.
- switch fmt {
- case 'e', 'E':
- d.Round(prec + 1)
- case 'f':
- d.Round(d.dp + prec)
- case 'g', 'G':
- if prec == 0 {
- prec = 1
- }
- d.Round(prec)
- }
- digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
- }
- return formatDigits(dst, shortest, neg, digs, prec, fmt)
-}
-
-func formatDigits(dst []byte, shortest bool, neg bool, digs decimalSlice, prec int, fmt byte) []byte {
- switch fmt {
- case 'e', 'E':
- return fmtE(dst, neg, digs, prec, fmt)
- case 'f':
- return fmtF(dst, neg, digs, prec)
- case 'g', 'G':
- // trailing fractional zeros in 'e' form will be trimmed.
- eprec := prec
- if eprec > digs.nd && digs.nd >= digs.dp {
- eprec = digs.nd
- }
- // %e is used if the exponent from the conversion
- // is less than -4 or greater than or equal to the precision.
- // if precision was the shortest possible, use precision 6 for this decision.
- if shortest {
- eprec = 6
- }
- exp := digs.dp - 1
- if exp < -4 || exp >= eprec {
- if prec > digs.nd {
- prec = digs.nd
- }
- return fmtE(dst, neg, digs, prec-1, fmt+'e'-'g')
- }
- if prec > digs.dp {
- prec = digs.nd
- }
- return fmtF(dst, neg, digs, max(prec-digs.dp, 0))
- }
-
- // unknown format
- return append(dst, '%', fmt)
-}
-
-// roundShortest rounds d (= mant * 2^exp) to the shortest number of digits
-// that will let the original floating point value be precisely reconstructed.
-func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
- // If mantissa is zero, the number is zero; stop now.
- if mant == 0 {
- d.nd = 0
- return
- }
-
- // Compute upper and lower such that any decimal number
- // between upper and lower (possibly inclusive)
- // will round to the original floating point number.
-
- // We may see at once that the number is already shortest.
- //
- // Suppose d is not denormal, so that 2^exp <= d < 10^dp.
- // The closest shorter number is at least 10^(dp-nd) away.
- // The lower/upper bounds computed below are at distance
- // at most 2^(exp-mantbits).
- //
- // So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits),
- // or equivalently log2(10)*(dp-nd) > exp-mantbits.
- // It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32).
- minexp := flt.bias + 1 // minimum possible exponent
- if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) {
- // The number is already shortest.
- return
- }
-
- // d = mant << (exp - mantbits)
- // Next highest floating point number is mant+1 << exp-mantbits.
- // Our upper bound is halfway between, mant*2+1 << exp-mantbits-1.
- upper := new(decimal)
- upper.Assign(mant*2 + 1)
- upper.Shift(exp - int(flt.mantbits) - 1)
-
- // d = mant << (exp - mantbits)
- // Next lowest floating point number is mant-1 << exp-mantbits,
- // unless mant-1 drops the significant bit and exp is not the minimum exp,
- // in which case the next lowest is mant*2-1 << exp-mantbits-1.
- // Either way, call it mantlo << explo-mantbits.
- // Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1.
- var mantlo uint64
- var explo int
- if mant > 1<<flt.mantbits || exp == minexp {
- mantlo = mant - 1
- explo = exp
- } else {
- mantlo = mant*2 - 1
- explo = exp - 1
- }
- lower := new(decimal)
- lower.Assign(mantlo*2 + 1)
- lower.Shift(explo - int(flt.mantbits) - 1)
-
- // The upper and lower bounds are possible outputs only if
- // the original mantissa is even, so that IEEE round-to-even
- // would round to the original mantissa and not the neighbors.
- inclusive := mant%2 == 0
-
- // As we walk the digits we want to know whether rounding up would fall
- // within the upper bound. This is tracked by upperdelta:
- //
- // If upperdelta == 0, the digits of d and upper are the same so far.
- //
- // If upperdelta == 1, we saw a difference of 1 between d and upper on a
- // previous digit and subsequently only 9s for d and 0s for upper.
- // (Thus rounding up may fall outside the bound, if it is exclusive.)
- //
- // If upperdelta == 2, then the difference is greater than 1
- // and we know that rounding up falls within the bound.
- var upperdelta uint8
-
- // Now we can figure out the minimum number of digits required.
- // Walk along until d has distinguished itself from upper and lower.
- for ui := 0; ; ui++ {
- // lower, d, and upper may have the decimal points at different
- // places. In this case upper is the longest, so we iterate from
- // ui==0 and start li and mi at (possibly) -1.
- mi := ui - upper.dp + d.dp
- if mi >= d.nd {
- break
- }
- li := ui - upper.dp + lower.dp
- l := byte('0') // lower digit
- if li >= 0 && li < lower.nd {
- l = lower.d[li]
- }
- m := byte('0') // middle digit
- if mi >= 0 {
- m = d.d[mi]
- }
- u := byte('0') // upper digit
- if ui < upper.nd {
- u = upper.d[ui]
- }
-
- // Okay to round down (truncate) if lower has a different digit
- // or if lower is inclusive and is exactly the result of rounding
- // down (i.e., and we have reached the final digit of lower).
- okdown := l != m || inclusive && li+1 == lower.nd
-
- switch {
- case upperdelta == 0 && m+1 < u:
- // Example:
- // m = 12345xxx
- // u = 12347xxx
- upperdelta = 2
- case upperdelta == 0 && m != u:
- // Example:
- // m = 12345xxx
- // u = 12346xxx
- upperdelta = 1
- case upperdelta == 1 && (m != '9' || u != '0'):
- // Example:
- // m = 1234598x
- // u = 1234600x
- upperdelta = 2
- }
- // Okay to round up if upper has a different digit and either upper
- // is inclusive or upper is bigger than the result of rounding up.
- okup := upperdelta > 0 && (inclusive || upperdelta > 1 || ui+1 < upper.nd)
-
- // If it's okay to do either, then round to the nearest one.
- // If it's okay to do only one, do it.
- switch {
- case okdown && okup:
- d.Round(mi + 1)
- return
- case okdown:
- d.RoundDown(mi + 1)
- return
- case okup:
- d.RoundUp(mi + 1)
- return
- }
- }
-}
-
-type decimalSlice struct {
- d []byte
- nd, dp int
-}
-
-// %e: -d.ddddde±dd
-func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
- // sign
- if neg {
- dst = append(dst, '-')
- }
-
- // first digit
- ch := byte('0')
- if d.nd != 0 {
- ch = d.d[0]
- }
- dst = append(dst, ch)
-
- // .moredigits
- if prec > 0 {
- dst = append(dst, '.')
- i := 1
- m := min(d.nd, prec+1)
- if i < m {
- dst = append(dst, d.d[i:m]...)
- i = m
- }
- for ; i <= prec; i++ {
- dst = append(dst, '0')
- }
- }
-
- // e±
- dst = append(dst, fmt)
- exp := d.dp - 1
- if d.nd == 0 { // special case: 0 has exponent 0
- exp = 0
- }
- if exp < 0 {
- ch = '-'
- exp = -exp
- } else {
- ch = '+'
- }
- dst = append(dst, ch)
-
- // dd or ddd
- switch {
- case exp < 10:
- dst = append(dst, '0', byte(exp)+'0')
- case exp < 100:
- dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0')
- default:
- dst = append(dst, byte(exp/100)+'0', byte(exp/10)%10+'0', byte(exp%10)+'0')
- }
-
- return dst
-}
-
-// %f: -ddddddd.ddddd
-func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
- // sign
- if neg {
- dst = append(dst, '-')
- }
-
- // integer, padded with zeros as needed.
- if d.dp > 0 {
- m := min(d.nd, d.dp)
- dst = append(dst, d.d[:m]...)
- for ; m < d.dp; m++ {
- dst = append(dst, '0')
- }
- } else {
- dst = append(dst, '0')
- }
-
- // fraction
- if prec > 0 {
- dst = append(dst, '.')
- for i := 0; i < prec; i++ {
- ch := byte('0')
- if j := d.dp + i; 0 <= j && j < d.nd {
- ch = d.d[j]
- }
- dst = append(dst, ch)
- }
- }
-
- return dst
-}
-
-// %b: -ddddddddp±ddd
-func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
- // sign
- if neg {
- dst = append(dst, '-')
- }
-
- // mantissa
- dst = AppendUint(dst, mant, 10)
-
- // p
- dst = append(dst, 'p')
-
- // ±exponent
- exp -= int(flt.mantbits)
- if exp >= 0 {
- dst = append(dst, '+')
- }
- dst = AppendInt(dst, int64(exp), 10)
-
- return dst
-}
-
-// %x: -0x1.yyyyyyyyp±ddd or -0x0p+0. (y is hex digit, d is decimal digit)
-func fmtX(dst []byte, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
- if mant == 0 {
- exp = 0
- }
-
- // Shift digits so leading 1 (if any) is at bit 1<<60.
- mant <<= 60 - flt.mantbits
- for mant != 0 && mant&(1<<60) == 0 {
- mant <<= 1
- exp--
- }
-
- // Round if requested.
- if prec >= 0 && prec < 15 {
- shift := uint(prec * 4)
- extra := (mant << shift) & (1<<60 - 1)
- mant >>= 60 - shift
- if extra|(mant&1) > 1<<59 {
- mant++
- }
- mant <<= 60 - shift
- if mant&(1<<61) != 0 {
- // Wrapped around.
- mant >>= 1
- exp++
- }
- }
-
- hex := lowerhex
- if fmt == 'X' {
- hex = upperhex
- }
-
- // sign, 0x, leading digit
- if neg {
- dst = append(dst, '-')
- }
- dst = append(dst, '0', fmt, '0'+byte((mant>>60)&1))
-
- // .fraction
- mant <<= 4 // remove leading 0 or 1
- if prec < 0 && mant != 0 {
- dst = append(dst, '.')
- for mant != 0 {
- dst = append(dst, hex[(mant>>60)&15])
- mant <<= 4
- }
- } else if prec > 0 {
- dst = append(dst, '.')
- for i := 0; i < prec; i++ {
- dst = append(dst, hex[(mant>>60)&15])
- mant <<= 4
- }
- }
-
- // p±
- ch := byte('P')
- if fmt == lower(fmt) {
- ch = 'p'
- }
- dst = append(dst, ch)
- if exp < 0 {
- ch = '-'
- exp = -exp
- } else {
- ch = '+'
- }
- dst = append(dst, ch)
-
- // dd or ddd or dddd
- switch {
- case exp < 100:
- dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0')
- case exp < 1000:
- dst = append(dst, byte(exp/100)+'0', byte((exp/10)%10)+'0', byte(exp%10)+'0')
- default:
- dst = append(dst, byte(exp/1000)+'0', byte(exp/100)%10+'0', byte((exp/10)%10)+'0', byte(exp%10)+'0')
- }
-
- return dst
-}
diff --git a/src/strconv/ftoa_test.go b/src/strconv/ftoa_test.go
deleted file mode 100644
index 40faa433a6..0000000000
--- a/src/strconv/ftoa_test.go
+++ /dev/null
@@ -1,336 +0,0 @@
-// 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 (
- "math"
- "math/rand"
- . "strconv"
- "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"},
- {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"},
-
- // 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"},
- {108678236358137.625, 'g', -1, "1.0867823635813762e+14"},
-
- {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"},
-
- // 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"},
-}
-
-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))
- }
- }
- }
-}
-
-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 {
- t.Errorf("%b printed as %s, want %s", x, 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},
- {"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},
- {"32Shortest", 1.234567e-8, 'g', -1, 32},
- {"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},
- {"64Fixed3", 1.23456e+78, 'e', 3, 64},
- {"64Fixed4", 1.23456e-78, 'e', 3, 64},
- {"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},
-
- // Trigger slow path (see issue #15672).
- // 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)
- }
- })
- }
-}
diff --git a/src/strconv/ftoaryu.go b/src/strconv/ftoaryu.go
deleted file mode 100644
index 9349df955f..0000000000
--- a/src/strconv/ftoaryu.go
+++ /dev/null
@@ -1,524 +0,0 @@
-// Copyright 2021 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
-
-import (
- "math/bits"
-)
-
-// binary to decimal conversion using the Ryū algorithm.
-//
-// See Ulf Adams, "Ryū: Fast Float-to-String Conversion" (doi:10.1145/3192366.3192369)
-//
-// Fixed precision formatting is a variant of the original paper's
-// algorithm, where a single multiplication by 10^k is required,
-// sharing the same rounding guarantees.
-
-// ryuFtoaFixed32 formats mant*(2^exp) with prec decimal digits.
-func ryuFtoaFixed32(d *decimalSlice, mant uint32, exp int, prec int) {
- if prec < 0 {
- panic("ryuFtoaFixed32 called with negative prec")
- }
- if prec > 9 {
- panic("ryuFtoaFixed32 called with prec > 9")
- }
- // Zero input.
- if mant == 0 {
- d.nd, d.dp = 0, 0
- return
- }
- // Renormalize to a 25-bit mantissa.
- e2 := exp
- if b := bits.Len32(mant); b < 25 {
- mant <<= uint(25 - b)
- e2 += b - 25
- }
- // Choose an exponent such that rounded mant*(2^e2)*(10^q) has
- // at least prec decimal digits, i.e
- // mant*(2^e2)*(10^q) >= 10^(prec-1)
- // Because mant >= 2^24, it is enough to choose:
- // 2^(e2+24) >= 10^(-q+prec-1)
- // or q = -mulLog10_2(e2+24) + prec - 1
- q := -mulLog10_2(e2+24) + prec - 1
-
- // Now compute mant*(2^e2)*(10^q).
- // Is it an exact computation?
- // Only small positive powers of 10 are exact (5^28 has 66 bits).
- exact := q <= 27 && q >= 0
-
- di, dexp2, d0 := mult64bitPow10(mant, e2, q)
- if dexp2 >= 0 {
- panic("not enough significant bits after mult64bitPow10")
- }
- // As a special case, computation might still be exact, if exponent
- // was negative and if it amounts to computing an exact division.
- // In that case, we ignore all lower bits.
- // Note that division by 10^11 cannot be exact as 5^11 has 26 bits.
- if q < 0 && q >= -10 && divisibleByPower5(uint64(mant), -q) {
- exact = true
- d0 = true
- }
- // Remove extra lower bits and keep rounding info.
- extra := uint(-dexp2)
- extraMask := uint32(1<<extra - 1)
-
- di, dfrac := di>>extra, di&extraMask
- roundUp := false
- if exact {
- // If we computed an exact product, d + 1/2
- // should round to d+1 if 'd' is odd.
- roundUp = dfrac > 1<<(extra-1) ||
- (dfrac == 1<<(extra-1) && !d0) ||
- (dfrac == 1<<(extra-1) && d0 && di&1 == 1)
- } else {
- // otherwise, d+1/2 always rounds up because
- // we truncated below.
- roundUp = dfrac>>(extra-1) == 1
- }
- if dfrac != 0 {
- d0 = false
- }
- // Proceed to the requested number of digits
- formatDecimal(d, uint64(di), !d0, roundUp, prec)
- // Adjust exponent
- d.dp -= q
-}
-
-// ryuFtoaFixed64 formats mant*(2^exp) with prec decimal digits.
-func ryuFtoaFixed64(d *decimalSlice, mant uint64, exp int, prec int) {
- if prec > 18 {
- panic("ryuFtoaFixed64 called with prec > 18")
- }
- // Zero input.
- if mant == 0 {
- d.nd, d.dp = 0, 0
- return
- }
- // Renormalize to a 55-bit mantissa.
- e2 := exp
- if b := bits.Len64(mant); b < 55 {
- mant = mant << uint(55-b)
- e2 += b - 55
- }
- // Choose an exponent such that rounded mant*(2^e2)*(10^q) has
- // at least prec decimal digits, i.e
- // mant*(2^e2)*(10^q) >= 10^(prec-1)
- // Because mant >= 2^54, it is enough to choose:
- // 2^(e2+54) >= 10^(-q+prec-1)
- // or q = -mulLog10_2(e2+54) + prec - 1
- //
- // The minimal required exponent is -mulLog10_2(1025)+18 = -291
- // The maximal required exponent is mulLog10_2(1074)+18 = 342
- q := -mulLog10_2(e2+54) + prec - 1
-
- // Now compute mant*(2^e2)*(10^q).
- // Is it an exact computation?
- // Only small positive powers of 10 are exact (5^55 has 128 bits).
- exact := q <= 55 && q >= 0
-
- di, dexp2, d0 := mult128bitPow10(mant, e2, q)
- if dexp2 >= 0 {
- panic("not enough significant bits after mult128bitPow10")
- }
- // As a special case, computation might still be exact, if exponent
- // was negative and if it amounts to computing an exact division.
- // In that case, we ignore all lower bits.
- // Note that division by 10^23 cannot be exact as 5^23 has 54 bits.
- if q < 0 && q >= -22 && divisibleByPower5(mant, -q) {
- exact = true
- d0 = true
- }
- // Remove extra lower bits and keep rounding info.
- extra := uint(-dexp2)
- extraMask := uint64(1<<extra - 1)
-
- di, dfrac := di>>extra, di&extraMask
- roundUp := false
- if exact {
- // If we computed an exact product, d + 1/2
- // should round to d+1 if 'd' is odd.
- roundUp = dfrac > 1<<(extra-1) ||
- (dfrac == 1<<(extra-1) && !d0) ||
- (dfrac == 1<<(extra-1) && d0 && di&1 == 1)
- } else {
- // otherwise, d+1/2 always rounds up because
- // we truncated below.
- roundUp = dfrac>>(extra-1) == 1
- }
- if dfrac != 0 {
- d0 = false
- }
- // Proceed to the requested number of digits
- formatDecimal(d, di, !d0, roundUp, prec)
- // Adjust exponent
- d.dp -= q
-}
-
-var uint64pow10 = [...]uint64{
- 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
- 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
-}
-
-// formatDecimal fills d with at most prec decimal digits
-// of mantissa m. The boolean trunc indicates whether m
-// is truncated compared to the original number being formatted.
-func formatDecimal(d *decimalSlice, m uint64, trunc bool, roundUp bool, prec int) {
- max := uint64pow10[prec]
- trimmed := 0
- for m >= max {
- a, b := m/10, m%10
- m = a
- trimmed++
- if b > 5 {
- roundUp = true
- } else if b < 5 {
- roundUp = false
- } else { // b == 5
- // round up if there are trailing digits,
- // or if the new value of m is odd (round-to-even convention)
- roundUp = trunc || m&1 == 1
- }
- if b != 0 {
- trunc = true
- }
- }
- if roundUp {
- m++
- }
- if m >= max {
- // Happens if di was originally 99999....xx
- m /= 10
- trimmed++
- }
- // render digits
- formatBase10(d.d[:prec], m)
- d.nd = prec
- for d.d[d.nd-1] == '0' {
- d.nd--
- trimmed++
- }
- d.dp = d.nd + trimmed
-}
-
-// ryuFtoaShortest formats mant*2^exp with prec decimal digits.
-func ryuFtoaShortest(d *decimalSlice, mant uint64, exp int, flt *floatInfo) {
- if mant == 0 {
- d.nd, d.dp = 0, 0
- return
- }
- // If input is an exact integer with fewer bits than the mantissa,
- // the previous and next integer are not admissible representations.
- if exp <= 0 && bits.TrailingZeros64(mant) >= -exp {
- mant >>= uint(-exp)
- ryuDigits(d, mant, mant, mant, true, false)
- return
- }
- ml, mc, mu, e2 := computeBounds(mant, exp, flt)
- if e2 == 0 {
- ryuDigits(d, ml, mc, mu, true, false)
- return
- }
- // Find 10^q *larger* than 2^-e2
- q := mulLog10_2(-e2) + 1
-
- // We are going to multiply by 10^q using 128-bit arithmetic.
- // The exponent is the same for all 3 numbers.
- var dl, dc, du uint64
- var dl0, dc0, du0 bool
- if flt == &float32info {
- var dl32, dc32, du32 uint32
- dl32, _, dl0 = mult64bitPow10(uint32(ml), e2, q)
- dc32, _, dc0 = mult64bitPow10(uint32(mc), e2, q)
- du32, e2, du0 = mult64bitPow10(uint32(mu), e2, q)
- dl, dc, du = uint64(dl32), uint64(dc32), uint64(du32)
- } else {
- dl, _, dl0 = mult128bitPow10(ml, e2, q)
- dc, _, dc0 = mult128bitPow10(mc, e2, q)
- du, e2, du0 = mult128bitPow10(mu, e2, q)
- }
- if e2 >= 0 {
- panic("not enough significant bits after mult128bitPow10")
- }
- // Is it an exact computation?
- if q > 55 {
- // Large positive powers of ten are not exact
- dl0, dc0, du0 = false, false, false
- }
- if q < 0 && q >= -24 {
- // Division by a power of ten may be exact.
- // (note that 5^25 is a 59-bit number so division by 5^25 is never exact).
- if divisibleByPower5(ml, -q) {
- dl0 = true
- }
- if divisibleByPower5(mc, -q) {
- dc0 = true
- }
- if divisibleByPower5(mu, -q) {
- du0 = true
- }
- }
- // Express the results (dl, dc, du)*2^e2 as integers.
- // Extra bits must be removed and rounding hints computed.
- extra := uint(-e2)
- extraMask := uint64(1<<extra - 1)
- // Now compute the floored, integral base 10 mantissas.
- dl, fracl := dl>>extra, dl&extraMask
- dc, fracc := dc>>extra, dc&extraMask
- du, fracu := du>>extra, du&extraMask
- // Is it allowed to use 'du' as a result?
- // It is always allowed when it is truncated, but also
- // if it is exact and the original binary mantissa is even
- // When disallowed, we can subtract 1.
- uok := !du0 || fracu > 0
- if du0 && fracu == 0 {
- uok = mant&1 == 0
- }
- if !uok {
- du--
- }
- // Is 'dc' the correctly rounded base 10 mantissa?
- // The correct rounding might be dc+1
- cup := false // don't round up.
- if dc0 {
- // If we computed an exact product, the half integer
- // should round to next (even) integer if 'dc' is odd.
- cup = fracc > 1<<(extra-1) ||
- (fracc == 1<<(extra-1) && dc&1 == 1)
- } else {
- // otherwise, the result is a lower truncation of the ideal
- // result.
- cup = fracc>>(extra-1) == 1
- }
- // Is 'dl' an allowed representation?
- // Only if it is an exact value, and if the original binary mantissa
- // was even.
- lok := dl0 && fracl == 0 && (mant&1 == 0)
- if !lok {
- dl++
- }
- // We need to remember whether the trimmed digits of 'dc' are zero.
- c0 := dc0 && fracc == 0
- // render digits
- ryuDigits(d, dl, dc, du, c0, cup)
- d.dp -= q
-}
-
-// computeBounds returns a floating-point vector (l, c, u)×2^e2
-// where the mantissas are 55-bit (or 26-bit) integers, describing the interval
-// represented by the input float64 or float32.
-func computeBounds(mant uint64, exp int, flt *floatInfo) (lower, central, upper uint64, e2 int) {
- if mant != 1<<flt.mantbits || exp == flt.bias+1-int(flt.mantbits) {
- // regular case (or denormals)
- lower, central, upper = 2*mant-1, 2*mant, 2*mant+1
- e2 = exp - 1
- return
- } else {
- // border of an exponent
- lower, central, upper = 4*mant-1, 4*mant, 4*mant+2
- e2 = exp - 2
- return
- }
-}
-
-func ryuDigits(d *decimalSlice, lower, central, upper uint64,
- c0, cup bool) {
- lhi, llo := divmod1e9(lower)
- chi, clo := divmod1e9(central)
- uhi, ulo := divmod1e9(upper)
- if uhi == 0 {
- // only low digits (for denormals)
- ryuDigits32(d, llo, clo, ulo, c0, cup, 8)
- } else if lhi < uhi {
- // truncate 9 digits at once.
- if llo != 0 {
- lhi++
- }
- c0 = c0 && clo == 0
- cup = (clo > 5e8) || (clo == 5e8 && cup)
- ryuDigits32(d, lhi, chi, uhi, c0, cup, 8)
- d.dp += 9
- } else {
- d.nd = 0
- // emit high part
- n := uint(9)
- for v := chi; v > 0; {
- v1, v2 := v/10, v%10
- v = v1
- n--
- d.d[n] = byte(v2 + '0')
- }
- d.d = d.d[n:]
- d.nd = int(9 - n)
- // emit low part
- ryuDigits32(d, llo, clo, ulo,
- c0, cup, d.nd+8)
- }
- // trim trailing zeros
- for d.nd > 0 && d.d[d.nd-1] == '0' {
- d.nd--
- }
- // trim initial zeros
- for d.nd > 0 && d.d[0] == '0' {
- d.nd--
- d.dp--
- d.d = d.d[1:]
- }
-}
-
-// ryuDigits32 emits decimal digits for a number less than 1e9.
-func ryuDigits32(d *decimalSlice, lower, central, upper uint32,
- c0, cup bool, endindex int) {
- if upper == 0 {
- d.dp = endindex + 1
- return
- }
- trimmed := 0
- // Remember last trimmed digit to check for round-up.
- // c0 will be used to remember zeroness of following digits.
- cNextDigit := 0
- for upper > 0 {
- // Repeatedly compute:
- // l = Ceil(lower / 10^k)
- // c = Round(central / 10^k)
- // u = Floor(upper / 10^k)
- // and stop when c goes out of the (l, u) interval.
- l := (lower + 9) / 10
- c, cdigit := central/10, central%10
- u := upper / 10
- if l > u {
- // don't trim the last digit as it is forbidden to go below l
- // other, trim and exit now.
- break
- }
- // Check that we didn't cross the lower boundary.
- // The case where l < u but c == l-1 is essentially impossible,
- // but may happen if:
- // lower = ..11
- // central = ..19
- // upper = ..31
- // and means that 'central' is very close but less than
- // an integer ending with many zeros, and usually
- // the "round-up" logic hides the problem.
- if l == c+1 && c < u {
- c++
- cdigit = 0
- cup = false
- }
- trimmed++
- // Remember trimmed digits of c
- c0 = c0 && cNextDigit == 0
- cNextDigit = int(cdigit)
- lower, central, upper = l, c, u
- }
- // should we round up?
- if trimmed > 0 {
- cup = cNextDigit > 5 ||
- (cNextDigit == 5 && !c0) ||
- (cNextDigit == 5 && c0 && central&1 == 1)
- }
- if central < upper && cup {
- central++
- }
- // We know where the number ends, fill directly
- endindex -= trimmed
- v := central
- n := endindex
- for n > d.nd {
- v1, v2 := v/100, v%100
- d.d[n] = smalls[2*v2+1]
- d.d[n-1] = smalls[2*v2+0]
- n -= 2
- v = v1
- }
- if n == d.nd {
- d.d[n] = byte(v + '0')
- }
- d.nd = endindex + 1
- d.dp = d.nd + trimmed
-}
-
-// mult64bitPow10 takes a floating-point input with a 25-bit
-// mantissa and multiplies it with 10^q. The resulting mantissa
-// is m*P >> 57 where P is a 64-bit truncated power of 10.
-// It is typically 31 or 32-bit wide.
-// The returned boolean is true if all trimmed bits were zero.
-//
-// That is:
-//
-// m*2^e2 * round(10^q) = resM * 2^resE + ε
-// exact = ε == 0
-func mult64bitPow10(m uint32, e2, q int) (resM uint32, resE int, exact bool) {
- if q == 0 {
- // P == 1<<63
- return m << 6, e2 - 6, true
- }
- pow, exp2, ok := pow10(q)
- if !ok {
- // This never happens due to the range of float32/float64 exponent
- panic("mult64bitPow10: power of 10 is out of range")
- }
- if q < 0 {
- // Inverse powers of ten must be rounded up.
- pow.Hi++
- }
- hi, lo := bits.Mul64(uint64(m), pow.Hi)
- e2 += exp2 - 63 + 57
- return uint32(hi<<7 | lo>>57), e2, lo<<7 == 0
-}
-
-// mult128bitPow10 takes a floating-point input with a 55-bit
-// mantissa and multiplies it with 10^q. The resulting mantissa
-// is m*P >> 119 where P is a 128-bit truncated power of 10.
-// It is typically 63 or 64-bit wide.
-// The returned boolean is true is all trimmed bits were zero.
-//
-// That is:
-//
-// m*2^e2 * round(10^q) = resM * 2^resE + ε
-// exact = ε == 0
-func mult128bitPow10(m uint64, e2, q int) (resM uint64, resE int, exact bool) {
- if q == 0 {
- // P == 1<<127
- return m << 8, e2 - 8, true
- }
- pow, exp2, ok := pow10(q)
- if !ok {
- // This never happens due to the range of float32/float64 exponent
- panic("mult128bitPow10: power of 10 is out of range")
- }
- if q < 0 {
- // Inverse powers of ten must be rounded up.
- pow.Lo++
- }
- e2 += exp2 - 127 + 119
-
- hi, mid, lo := umul192(m, pow)
- return hi<<9 | mid>>55, e2, mid<<9 == 0 && lo == 0
-}
-
-func divisibleByPower5(m uint64, k int) bool {
- if m == 0 {
- return true
- }
- for i := 0; i < k; i++ {
- if m%5 != 0 {
- return false
- }
- m /= 5
- }
- return true
-}
-
-// divmod1e9 computes quotient and remainder of division by 1e9,
-// avoiding runtime uint64 division on 32-bit platforms.
-func divmod1e9(x uint64) (uint32, uint32) {
- if host64bit {
- return uint32(x / 1e9), uint32(x % 1e9)
- }
- // Use the same sequence of operations as the amd64 compiler.
- hi, _ := bits.Mul64(x>>1, 0x89705f4136b4a598) // binary digits of 1e-9
- q := hi >> 28
- return uint32(q), uint32(x - q*1e9)
-}
diff --git a/src/strconv/import_test.go b/src/strconv/import_test.go
index 05d957a623..b44678bc7c 100644
--- a/src/strconv/import_test.go
+++ b/src/strconv/import_test.go
@@ -6,15 +6,7 @@ package strconv_test
import . "strconv"
-type uint128 = Uint128
-
var (
- baseError = BaseError
- bitSizeError = BitSizeError
- mulLog10_2 = MulLog10_2
- mulLog2_10 = MulLog2_10
- parseFloatPrefix = ParseFloatPrefix
- pow10 = Pow10
- umul128 = Umul128
- umul192 = Umul192
+ baseError = BaseError
+ bitSizeError = BitSizeError
)
diff --git a/src/strconv/itoa.go b/src/strconv/itoa.go
deleted file mode 100644
index 7884e8e987..0000000000
--- a/src/strconv/itoa.go
+++ /dev/null
@@ -1,308 +0,0 @@
-// 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
-
-import (
- "math/bits"
- "runtime"
-)
-
-// FormatUint returns the string representation of i in the given base,
-// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
-// for digit values >= 10.
-func FormatUint(i uint64, base int) string {
- if base == 10 {
- if i < nSmalls {
- return small(int(i))
- }
- var a [24]byte
- j := formatBase10(a[:], i)
- return string(a[j:])
- }
- _, s := formatBits(nil, i, base, false, false)
- return s
-}
-
-// FormatInt returns the string representation of i in the given base,
-// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
-// for digit values >= 10.
-func FormatInt(i int64, base int) string {
- if base == 10 {
- if 0 <= i && i < nSmalls {
- return small(int(i))
- }
- var a [24]byte
- u := uint64(i)
- if i < 0 {
- u = -u
- }
- j := formatBase10(a[:], u)
- if i < 0 {
- j--
- a[j] = '-'
- }
- return string(a[j:])
- }
- _, s := formatBits(nil, uint64(i), base, i < 0, false)
- return s
-}
-
-// Itoa is equivalent to [FormatInt](int64(i), 10).
-func Itoa(i int) string {
- return FormatInt(int64(i), 10)
-}
-
-// AppendInt appends the string form of the integer i,
-// as generated by [FormatInt], to dst and returns the extended buffer.
-func AppendInt(dst []byte, i int64, base int) []byte {
- u := uint64(i)
- if i < 0 {
- dst = append(dst, '-')
- u = -u
- }
- return AppendUint(dst, u, base)
-}
-
-// AppendUint appends the string form of the unsigned integer i,
-// as generated by [FormatUint], to dst and returns the extended buffer.
-func AppendUint(dst []byte, i uint64, base int) []byte {
- if base == 10 {
- if i < nSmalls {
- return append(dst, small(int(i))...)
- }
- var a [24]byte
- j := formatBase10(a[:], i)
- return append(dst, a[j:]...)
- }
- dst, _ = formatBits(dst, i, base, false, true)
- return dst
-}
-
-const digits = "0123456789abcdefghijklmnopqrstuvwxyz"
-
-// formatBits computes the string representation of u in the given base.
-// If neg is set, u is treated as negative int64 value. If append_ is
-// set, the string is appended to dst and the resulting byte slice is
-// returned as the first result value; otherwise the string is returned
-// as the second result value.
-// The caller is expected to have handled base 10 separately for speed.
-func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s string) {
- if base < 2 || base == 10 || base > len(digits) {
- panic("strconv: illegal AppendInt/FormatInt base")
- }
- // 2 <= base && base <= len(digits)
-
- var a [64 + 1]byte // +1 for sign of 64bit value in base 2
- i := len(a)
- if neg {
- u = -u
- }
-
- // convert bits
- // We use uint values where we can because those will
- // fit into a single register even on a 32bit machine.
- if isPowerOfTwo(base) {
- // Use shifts and masks instead of / and %.
- shift := uint(bits.TrailingZeros(uint(base)))
- b := uint64(base)
- m := uint(base) - 1 // == 1<<shift - 1
- for u >= b {
- i--
- a[i] = digits[uint(u)&m]
- u >>= shift
- }
- // u < base
- i--
- a[i] = digits[uint(u)]
- } else {
- // general case
- b := uint64(base)
- for u >= b {
- i--
- // Avoid using r = a%b in addition to q = a/b
- // since 64bit division and modulo operations
- // are calculated by runtime functions on 32bit machines.
- q := u / b
- a[i] = digits[uint(u-q*b)]
- u = q
- }
- // u < base
- i--
- a[i] = digits[uint(u)]
- }
-
- // add sign, if any
- if neg {
- i--
- a[i] = '-'
- }
-
- if append_ {
- d = append(dst, a[i:]...)
- return
- }
- s = string(a[i:])
- return
-}
-
-func isPowerOfTwo(x int) bool {
- return x&(x-1) == 0
-}
-
-const nSmalls = 100
-
-// smalls is the formatting of 00..99 concatenated.
-// It is then padded out with 56 x's to 256 bytes,
-// so that smalls[x&0xFF] has no bounds check.
-//
-// TODO(rsc): Once the compiler does a better job
-// at tracking mod bounds, the &0xFF should not be needed:
-// go.dev/issue/75954 and go.dev/issue/63110.
-const smalls = "00010203040506070809" +
- "10111213141516171819" +
- "20212223242526272829" +
- "30313233343536373839" +
- "40414243444546474849" +
- "50515253545556575859" +
- "60616263646566676869" +
- "70717273747576777879" +
- "80818283848586878889" +
- "90919293949596979899" +
- "xxxxxxxxxxxxxxxxxxxx" +
- "xxxxxxxxxxxxxxxxxxxx" +
- "xxxxxxxxxxxxxxxxxxxx" +
- "xxxxxxxxxxxxxxxxxxxx" +
- "xxxxxxxxxxxxxxxxxxxx" +
- "xxxxxx"
-
-const host64bit = ^uint(0)>>32 != 0
-
-// small returns the string for an i with 0 <= i < nSmalls.
-func small(i int) string {
- if i < 10 {
- return digits[i : i+1]
- }
- return smalls[i*2 : i*2+2]
-}
-
-// formatBase10 formats the decimal representation of u into the tail of a
-// and returns the offset of the first byte written to a. That is, after
-//
-// i := formatBase10(a, u)
-//
-// the decimal representation is in a[i:].
-func formatBase10(a []byte, u uint64) int {
- // Decide implementation strategy based on architecture.
- const (
- // 64-bit systems can work in 64-bit math the whole time
- // or can split the uint64 into uint32-sized chunks.
- // On most systems, the uint32 math is faster, but not all.
- // The decision here is based on benchmarking.
- itoaPure64 = host64bit && runtime.GOARCH != "amd64" && runtime.GOARCH != "arm64" && runtime.GOARCH != "s390x"
-
- // 64-bit systems can all use 64-bit div and mod by a constant,
- // which the compiler rewrites to use 64x64→128-bit multiplies.
- itoaDivMod64 = host64bit // can use 64-bit div/mod by constant
- )
-
- if itoaPure64 {
- // Convert 2 digits at a time, using 64-bit math.
- i := len(a)
- u := uint(u)
- for u >= 100 {
- var dd uint
- u, dd = u/100, (u%100)*2
- i -= 2
- a[i+0], a[i+1] = smalls[(dd+0)&0xFF], smalls[(dd+1)&0xFF]
- }
-
- dd := u * 2
- i--
- a[i] = smalls[(dd+1)&0xFF]
- if u >= 10 {
- i--
- a[i] = smalls[(dd+0)&0xFF]
- }
- return i
- }
-
- // Convert 9-digit chunks using 32-bit math.
- // Most numbers are small, so the comparison u >= 1e9 is usually pure overhead,
- // so we approximate it by u>>29 != 0, which is usually faster and good enough.
- i := len(a)
- for (host64bit && u>>29 != 0) || (!host64bit && (u>>32 != 0 || uint32(u)>>29 != 0)) {
- var lo uint32
- if itoaDivMod64 {
- u, lo = u/1e9, uint32(u%1e9)
- } else {
- // On 64-bit systems the compiler rewrites the div and mod above
- // into a 64x64→128-bit multiply (https://godbolt.org/z/EPnK8zvMK):
- // hi, _ := bits.Mul64(u>>1, 0x89705f4136b4a598)
- // q := hi >> 28
- // lo = uint32(u - q*1e9)
- // u = q
- // On 32-bit systems, the compiler invokes a uint64 software divide,
- // which is quite slow. We could write the bits.Mul64 code above
- // but even that is slower than we'd like, since it calls a software mul64
- // instead of having a hardware instruction to use.
- // Instead we inline bits.Mul64 here and change y0/y1 to constants.
- // The compiler does use direct 32x32→64-bit multiplies for this code.
- //
- // For lots more about division by multiplication see Warren, _Hacker's Delight_.
- // For a concise overview, see the first two sections of
- // https://ridiculousfish.com/blog/posts/labor-of-division-episode-iii.html.
- const mask32 = 1<<32 - 1
- x0 := ((u >> 1) & mask32)
- x1 := (u >> 1) >> 32
- const y0 = 0x36b4a598
- const y1 = 0x89705f41
- w0 := x0 * y0
- t := x1*y0 + w0>>32
- w1 := t & mask32
- w2 := t >> 32
- w1 += x0 * y1
- hi := x1*y1 + w2 + w1>>32
- q := hi >> 28
-
- lo = uint32(u) - uint32(q)*1e9 // uint32(u - q*1e9) but faster
- u = q
- }
-
- // Convert 9 digits.
- for range 4 {
- var dd uint32
- lo, dd = lo/100, (lo%100)*2
- i -= 2
- a[i+0], a[i+1] = smalls[(dd+0)&0xFF], smalls[(dd+1)&0xFF]
- }
- i--
- a[i] = smalls[(lo*2+1)&0xFF]
-
- // If we'd been using u >= 1e9 then we would be guaranteed that u/1e9 > 0,
- // but since we used u>>29 != 0, u/1e9 might be 0, so we might be done.
- // (If u is now 0, then at the start we had 2²⁹ ≤ u < 10⁹, so it was still correct
- // to write 9 digits; we have not accidentally written any leading zeros.)
- if u == 0 {
- return i
- }
- }
-
- // Convert final chunk, at most 8 digits.
- lo := uint32(u)
- for lo >= 100 {
- var dd uint32
- lo, dd = lo/100, (lo%100)*2
- i -= 2
- a[i+0], a[i+1] = smalls[(dd+0)&0xFF], smalls[(dd+1)&0xFF]
- }
- i--
- dd := lo * 2
- a[i] = smalls[(dd+1)&0xFF]
- if lo >= 10 {
- i--
- a[i] = smalls[(dd+0)&0xFF]
- }
- return i
-}
diff --git a/src/strconv/itoa_test.go b/src/strconv/itoa_test.go
deleted file mode 100644
index 9dbf812d4b..0000000000
--- a/src/strconv/itoa_test.go
+++ /dev/null
@@ -1,244 +0,0 @@
-// 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 (
- "fmt"
- . "strconv"
- "testing"
-)
-
-type itob64Test struct {
- in int64
- base int
- out string
-}
-
-var itob64tests = []itob64Test{
- {0, 10, "0"},
- {1, 10, "1"},
- {-1, 10, "-1"},
- {12345678, 10, "12345678"},
- {-987654321, 10, "-987654321"},
- {1<<31 - 1, 10, "2147483647"},
- {-1<<31 + 1, 10, "-2147483647"},
- {1 << 31, 10, "2147483648"},
- {-1 << 31, 10, "-2147483648"},
- {1<<31 + 1, 10, "2147483649"},
- {-1<<31 - 1, 10, "-2147483649"},
- {1<<32 - 1, 10, "4294967295"},
- {-1<<32 + 1, 10, "-4294967295"},
- {1 << 32, 10, "4294967296"},
- {-1 << 32, 10, "-4294967296"},
- {1<<32 + 1, 10, "4294967297"},
- {-1<<32 - 1, 10, "-4294967297"},
- {1 << 50, 10, "1125899906842624"},
- {1<<63 - 1, 10, "9223372036854775807"},
- {-1<<63 + 1, 10, "-9223372036854775807"},
- {-1 << 63, 10, "-9223372036854775808"},
-
- {0, 2, "0"},
- {10, 2, "1010"},
- {-1, 2, "-1"},
- {1 << 15, 2, "1000000000000000"},
-
- {-8, 8, "-10"},
- {057635436545, 8, "57635436545"},
- {1 << 24, 8, "100000000"},
-
- {16, 16, "10"},
- {-0x123456789abcdef, 16, "-123456789abcdef"},
- {1<<63 - 1, 16, "7fffffffffffffff"},
- {1<<63 - 1, 2, "111111111111111111111111111111111111111111111111111111111111111"},
- {-1 << 63, 2, "-1000000000000000000000000000000000000000000000000000000000000000"},
-
- {16, 17, "g"},
- {25, 25, "10"},
- {(((((17*35+24)*35+21)*35+34)*35+12)*35+24)*35 + 32, 35, "holycow"},
- {(((((17*36+24)*36+21)*36+34)*36+12)*36+24)*36 + 32, 36, "holycow"},
-}
-
-func TestItoa(t *testing.T) {
- for _, test := range itob64tests {
- s := FormatInt(test.in, test.base)
- if s != test.out {
- t.Errorf("FormatInt(%v, %v) = %v want %v",
- test.in, test.base, s, test.out)
- }
- x := AppendInt([]byte("abc"), test.in, test.base)
- if string(x) != "abc"+test.out {
- t.Errorf("AppendInt(%q, %v, %v) = %q want %v",
- "abc", test.in, test.base, x, test.out)
- }
-
- if test.in >= 0 {
- s := FormatUint(uint64(test.in), test.base)
- if s != test.out {
- t.Errorf("FormatUint(%v, %v) = %v want %v",
- test.in, test.base, s, test.out)
- }
- x := AppendUint(nil, uint64(test.in), test.base)
- if string(x) != test.out {
- t.Errorf("AppendUint(%q, %v, %v) = %q want %v",
- "abc", uint64(test.in), test.base, x, test.out)
- }
- }
-
- if test.base == 10 && int64(int(test.in)) == test.in {
- s := Itoa(int(test.in))
- if s != test.out {
- t.Errorf("Itoa(%v) = %v want %v",
- test.in, s, test.out)
- }
- }
- }
-
- // Override when base is illegal
- defer func() {
- if r := recover(); r == nil {
- t.Fatalf("expected panic due to illegal base")
- }
- }()
- FormatUint(12345678, 1)
-}
-
-type uitob64Test struct {
- in uint64
- base int
- out string
-}
-
-var uitob64tests = []uitob64Test{
- {1<<63 - 1, 10, "9223372036854775807"},
- {1 << 63, 10, "9223372036854775808"},
- {1<<63 + 1, 10, "9223372036854775809"},
- {1<<64 - 2, 10, "18446744073709551614"},
- {1<<64 - 1, 10, "18446744073709551615"},
- {1<<64 - 1, 2, "1111111111111111111111111111111111111111111111111111111111111111"},
-}
-
-func TestUitoa(t *testing.T) {
- for _, test := range uitob64tests {
- s := FormatUint(test.in, test.base)
- if s != test.out {
- t.Errorf("FormatUint(%v, %v) = %v want %v",
- test.in, test.base, s, test.out)
- }
- x := AppendUint([]byte("abc"), test.in, test.base)
- if string(x) != "abc"+test.out {
- t.Errorf("AppendUint(%q, %v, %v) = %q want %v",
- "abc", test.in, test.base, x, test.out)
- }
-
- }
-}
-
-var varlenUints = []struct {
- in uint64
- out string
-}{
- {1, "1"},
- {12, "12"},
- {123, "123"},
- {1234, "1234"},
- {12345, "12345"},
- {123456, "123456"},
- {1234567, "1234567"},
- {12345678, "12345678"},
- {123456789, "123456789"},
- {1234567890, "1234567890"},
- {12345678901, "12345678901"},
- {123456789012, "123456789012"},
- {1234567890123, "1234567890123"},
- {12345678901234, "12345678901234"},
- {123456789012345, "123456789012345"},
- {1234567890123456, "1234567890123456"},
- {12345678901234567, "12345678901234567"},
- {123456789012345678, "123456789012345678"},
- {1234567890123456789, "1234567890123456789"},
- {12345678901234567890, "12345678901234567890"},
-}
-
-func TestFormatUintVarlen(t *testing.T) {
- for _, test := range varlenUints {
- s := FormatUint(test.in, 10)
- if s != test.out {
- t.Errorf("FormatUint(%v, 10) = %v want %v", test.in, s, test.out)
- }
- }
-}
-
-func BenchmarkFormatInt(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, test := range itob64tests {
- s := FormatInt(test.in, test.base)
- BenchSink += len(s)
- }
- }
-}
-
-func BenchmarkAppendInt(b *testing.B) {
- dst := make([]byte, 0, 30)
- for i := 0; i < b.N; i++ {
- for _, test := range itob64tests {
- dst = AppendInt(dst[:0], test.in, test.base)
- BenchSink += len(dst)
- }
- }
-}
-
-func BenchmarkFormatUint(b *testing.B) {
- for i := 0; i < b.N; i++ {
- for _, test := range uitob64tests {
- s := FormatUint(test.in, test.base)
- BenchSink += len(s)
- }
- }
-}
-
-func BenchmarkAppendUint(b *testing.B) {
- dst := make([]byte, 0, 30)
- for i := 0; i < b.N; i++ {
- for _, test := range uitob64tests {
- dst = AppendUint(dst[:0], test.in, test.base)
- BenchSink += len(dst)
- }
- }
-}
-
-func BenchmarkFormatIntSmall(b *testing.B) {
- smallInts := []int64{7, 42}
- for _, smallInt := range smallInts {
- b.Run(Itoa(int(smallInt)), func(b *testing.B) {
- for i := 0; i < b.N; i++ {
- s := FormatInt(smallInt, 10)
- BenchSink += len(s)
- }
- })
- }
-}
-
-func BenchmarkAppendIntSmall(b *testing.B) {
- dst := make([]byte, 0, 30)
- const smallInt = 42
- for i := 0; i < b.N; i++ {
- dst = AppendInt(dst[:0], smallInt, 10)
- BenchSink += len(dst)
- }
-}
-
-func BenchmarkAppendUintVarlen(b *testing.B) {
- for _, test := range varlenUints {
- b.Run(fmt.Sprint("digits=", len(test.out)), func(b *testing.B) {
- dst := make([]byte, 0, 30)
- for j := 0; j < b.N; j++ {
- dst = AppendUint(dst[:0], test.in, 10)
- BenchSink += len(dst)
- }
- })
- }
-}
-
-var BenchSink int // make sure compiler cannot optimize away benchmarks
diff --git a/src/strconv/math.go b/src/strconv/math.go
deleted file mode 100644
index f0f3d5fe54..0000000000
--- a/src/strconv/math.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2025 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
-
-import "math/bits"
-
-// A uint128 is a 128-bit uint.
-// The fields are exported to make them visible to package strconv_test.
-type uint128 struct {
- Hi uint64
- Lo uint64
-}
-
-// umul128 returns the 128-bit product x*y.
-func umul128(x, y uint64) uint128 {
- hi, lo := bits.Mul64(x, y)
- return uint128{hi, lo}
-}
-
-// umul192 returns the 192-bit product x*y in three uint64s.
-func umul192(x uint64, y uint128) (hi, mid, lo uint64) {
- mid1, lo := bits.Mul64(x, y.Lo)
- hi, mid2 := bits.Mul64(x, y.Hi)
- mid, carry := bits.Add64(mid1, mid2, 0)
- return hi + carry, mid, lo
-}
-
-// pow10 returns the 128-bit mantissa and binary exponent of 10**e
-// If e is out of range, pow10 returns ok=false.
-func pow10(e int) (mant uint128, exp int, ok bool) {
- if e < pow10Min || e > pow10Max {
- return
- }
- return pow10Tab[e-pow10Min], mulLog2_10(e), true
-}
-
-// mulLog10_2 returns math.Floor(x * log(2)/log(10)) for an integer x in
-// the range -1600 <= x && x <= +1600.
-//
-// The range restriction lets us work in faster integer arithmetic instead of
-// slower floating point arithmetic. Correctness is verified by unit tests.
-func mulLog10_2(x int) int {
- // log(2)/log(10) ≈ 0.30102999566 ≈ 78913 / 2^18
- return (x * 78913) >> 18
-}
-
-// mulLog2_10 returns math.Floor(x * log(10)/log(2)) for an integer x in
-// the range -500 <= x && x <= +500.
-//
-// The range restriction lets us work in faster integer arithmetic instead of
-// slower floating point arithmetic. Correctness is verified by unit tests.
-func mulLog2_10(x int) int {
- // log(10)/log(2) ≈ 3.32192809489 ≈ 108853 / 2^15
- return (x * 108853) >> 15
-}
diff --git a/src/strconv/math_test.go b/src/strconv/math_test.go
deleted file mode 100644
index 19b7ea6c75..0000000000
--- a/src/strconv/math_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2025 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 (
- "math"
- . "strconv"
- "testing"
-)
-
-var pow10Tests = []struct {
- exp10 int
- mant uint128
- exp2 int
- ok bool
-}{
- {-349, uint128{0, 0}, 0, false},
- {-348, uint128{0xFA8FD5A0081C0288, 0x1732C869CD60E453}, -1157, true},
- {0, uint128{0x8000000000000000, 0x0000000000000000}, 0, true},
- {347, uint128{0xD13EB46469447567, 0x4B7195F2D2D1A9FB}, 1152, true},
- {348, uint128{0, 0}, 0, false},
-}
-
-func TestPow10(t *testing.T) {
- for _, tt := range pow10Tests {
- mant, exp2, ok := Pow10(tt.exp10)
- if mant != tt.mant || exp2 != tt.exp2 {
- t.Errorf("pow10(%d) = %#016x, %#016x, %d, %v want %#016x,%#016x, %d, %v",
- tt.exp10, mant.Hi, mant.Lo, exp2, ok,
- tt.mant.Hi, tt.mant.Lo, tt.exp2, tt.ok)
- }
- }
-}
-
-func u128(hi, lo uint64) uint128 {
- return uint128{Hi: hi, Lo: lo}
-}
-
-var umul192Tests = []struct {
- x uint64
- y uint128
- hi uint64
- mid uint64
- lo uint64
-}{
- {0, u128(0, 0), 0, 0, 0},
- {^uint64(0), u128(^uint64(0), ^uint64(0)), ^uint64(1), ^uint64(0), 1},
-}
-
-func TestUmul192(t *testing.T) {
- for _, tt := range umul192Tests {
- hi, mid, lo := Umul192(tt.x, tt.y)
- if hi != tt.hi || mid != tt.mid || lo != tt.lo {
- t.Errorf("umul192(%#x, {%#x,%#x}) = %#x, %#x, %#x, want %#x, %#x, %#x",
- tt.x, tt.y.Hi, tt.y.Lo, hi, mid, lo, tt.hi, tt.mid, tt.lo)
- }
- }
-}
-
-func TestMulLog10_2(t *testing.T) {
- for x := -1600; x <= +1600; x++ {
- iMath := mulLog10_2(x)
- fMath := int(math.Floor(float64(x) * math.Ln2 / math.Ln10))
- if iMath != fMath {
- t.Errorf("mulLog10_2(%d) failed: %d vs %d\n", x, iMath, fMath)
- }
- }
-}
-
-func TestMulLog2_10(t *testing.T) {
- for x := -500; x <= +500; x++ {
- iMath := mulLog2_10(x)
- fMath := int(math.Floor(float64(x) * math.Ln10 / math.Ln2))
- if iMath != fMath {
- t.Errorf("mulLog2_10(%d) failed: %d vs %d\n", x, iMath, fMath)
- }
- }
-}
diff --git a/src/strconv/number.go b/src/strconv/number.go
new file mode 100644
index 0000000000..3fa625c35f
--- /dev/null
+++ b/src/strconv/number.go
@@ -0,0 +1,286 @@
+// Copyright 2025 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
+
+import (
+ "errors"
+ "internal/strconv"
+ "internal/stringslite"
+)
+
+// IntSize is the size in bits of an int or uint value.
+const IntSize = strconv.IntSize
+
+// ParseBool returns the boolean value represented by the string.
+// It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.
+// Any other value returns an error.
+func ParseBool(str string) (bool, error) {
+ x, err := strconv.ParseBool(str)
+ if err != nil {
+ return x, toError("ParseBool", str, 0, 0, err)
+ }
+ return x, nil
+}
+
+// FormatBool returns "true" or "false" according to the value of b.
+func FormatBool(b bool) string {
+ return strconv.FormatBool(b)
+}
+
+// AppendBool appends "true" or "false", according to the value of b,
+// to dst and returns the extended buffer.
+func AppendBool(dst []byte, b bool) []byte {
+ return strconv.AppendBool(dst, b)
+}
+
+// ParseComplex converts the string s to a complex number
+// with the precision specified by bitSize: 64 for complex64, or 128 for complex128.
+// When bitSize=64, the result still has type complex128, but it will be
+// convertible to complex64 without changing its value.
+//
+// The number represented by s must be of the form N, Ni, or N±Ni, where N stands
+// for a floating-point number as recognized by [ParseFloat], and i is the imaginary
+// component. If the second N is unsigned, a + sign is required between the two components
+// as indicated by the ±. If the second N is NaN, only a + sign is accepted.
+// The form may be parenthesized and cannot contain any spaces.
+// The resulting complex number consists of the two components converted by ParseFloat.
+//
+// The errors that ParseComplex returns have concrete type [*NumError]
+// and include err.Num = s.
+//
+// If s is not syntactically well-formed, ParseComplex returns err.Err = ErrSyntax.
+//
+// If s is syntactically well-formed but either component is more than 1/2 ULP
+// away from the largest floating point number of the given component's size,
+// ParseComplex returns err.Err = ErrRange and c = ±Inf for the respective component.
+func ParseComplex(s string, bitSize int) (complex128, error) {
+ x, err := strconv.ParseComplex(s, bitSize)
+ if err != nil {
+ return x, toError("ParseComplex", s, 0, bitSize, err)
+ }
+ return x, nil
+}
+
+// ParseFloat converts the string s to a floating-point number
+// with the precision specified by bitSize: 32 for float32, or 64 for float64.
+// When bitSize=32, the result still has type float64, but it will be
+// convertible to float32 without changing its value.
+//
+// ParseFloat accepts decimal and hexadecimal floating-point numbers
+// as defined by the Go syntax for [floating-point literals].
+// If s is well-formed and near a valid floating-point number,
+// ParseFloat returns the nearest floating-point number rounded
+// using IEEE754 unbiased rounding.
+// (Parsing a hexadecimal floating-point value only rounds when
+// there are more bits in the hexadecimal representation than
+// will fit in the mantissa.)
+//
+// The errors that ParseFloat returns have concrete type *NumError
+// and include err.Num = s.
+//
+// If s is not syntactically well-formed, ParseFloat returns err.Err = ErrSyntax.
+//
+// If s is syntactically well-formed but is more than 1/2 ULP
+// away from the largest floating point number of the given size,
+// ParseFloat returns f = ±Inf, err.Err = ErrRange.
+//
+// ParseFloat recognizes the string "NaN", and the (possibly signed) strings "Inf" and "Infinity"
+// as their respective special floating point values. It ignores case when matching.
+//
+// [floating-point literals]: https://go.dev/ref/spec#Floating-point_literals
+func ParseFloat(s string, bitSize int) (float64, error) {
+ x, err := strconv.ParseFloat(s, bitSize)
+ if err != nil {
+ return x, toError("ParseFloat", s, 0, bitSize, err)
+ }
+ return x, nil
+}
+
+// ParseUint is like [ParseInt] but for unsigned numbers.
+//
+// A sign prefix is not permitted.
+func ParseUint(s string, base int, bitSize int) (uint64, error) {
+ x, err := strconv.ParseUint(s, base, bitSize)
+ if err != nil {
+ return x, toError("ParseUint", s, base, bitSize, err)
+ }
+ return x, nil
+}
+
+// ParseInt interprets a string s in the given base (0, 2 to 36) and
+// bit size (0 to 64) and returns the corresponding value i.
+//
+// The string may begin with a leading sign: "+" or "-".
+//
+// If the base argument is 0, the true base is implied by the string's
+// prefix following the sign (if present): 2 for "0b", 8 for "0" or "0o",
+// 16 for "0x", and 10 otherwise. Also, for argument base 0 only,
+// underscore characters are permitted as defined by the Go syntax for
+// [integer literals].
+//
+// The bitSize argument specifies the integer type
+// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
+// correspond to int, int8, int16, int32, and int64.
+// If bitSize is below 0 or above 64, an error is returned.
+//
+// The errors that ParseInt returns have concrete type [*NumError]
+// and include err.Num = s. If s is empty or contains invalid
+// digits, err.Err = [ErrSyntax] and the returned value is 0;
+// if the value corresponding to s cannot be represented by a
+// signed integer of the given size, err.Err = [ErrRange] and the
+// returned value is the maximum magnitude integer of the
+// appropriate bitSize and sign.
+//
+// [integer literals]: https://go.dev/ref/spec#Integer_literals
+func ParseInt(s string, base int, bitSize int) (i int64, err error) {
+ x, err := strconv.ParseInt(s, base, bitSize)
+ if err != nil {
+ return x, toError("ParseInt", s, base, bitSize, err)
+ }
+ return x, nil
+}
+
+// Atoi is equivalent to ParseInt(s, 10, 0), converted to type int.
+func Atoi(s string) (int, error) {
+ x, err := strconv.Atoi(s)
+ if err != nil {
+ return x, toError("Atoi", s, 0, 0, err)
+ }
+ return strconv.Atoi(s)
+}
+
+// FormatComplex converts the complex number c to a string of the
+// form (a+bi) where a and b are the real and imaginary parts,
+// formatted according to the format fmt and precision prec.
+//
+// The format fmt and precision prec have the same meaning as in [FormatFloat].
+// It rounds the result assuming that the original was obtained from a complex
+// value of bitSize bits, which must be 64 for complex64 and 128 for complex128.
+func FormatComplex(c complex128, fmt byte, prec, bitSize int) string {
+ return strconv.FormatComplex(c, fmt, prec, bitSize)
+}
+
+// FormatFloat converts the floating-point number f to a string,
+// according to the format fmt and precision prec. It rounds the
+// result assuming that the original was obtained from a floating-point
+// value of bitSize bits (32 for float32, 64 for float64).
+//
+// The format fmt is one of
+// - 'b' (-ddddp±ddd, a binary exponent),
+// - 'e' (-d.dddde±dd, a decimal exponent),
+// - 'E' (-d.ddddE±dd, a decimal exponent),
+// - 'f' (-ddd.dddd, no exponent),
+// - 'g' ('e' for large exponents, 'f' otherwise),
+// - 'G' ('E' for large exponents, 'f' otherwise),
+// - 'x' (-0xd.ddddp±ddd, a hexadecimal fraction and binary exponent), or
+// - 'X' (-0Xd.ddddP±ddd, a hexadecimal fraction and binary exponent).
+//
+// The precision prec controls the number of digits (excluding the exponent)
+// printed by the 'e', 'E', 'f', 'g', 'G', 'x', and 'X' formats.
+// For 'e', 'E', 'f', 'x', and 'X', it is the number of digits after the decimal point.
+// For 'g' and 'G' it is the maximum number of significant digits (trailing
+// zeros are removed).
+// The special precision -1 uses the smallest number of digits
+// necessary such that ParseFloat will return f exactly.
+// The exponent is written as a decimal integer;
+// for all formats other than 'b', it will be at least two digits.
+func FormatFloat(f float64, fmt byte, prec, bitSize int) string {
+ return strconv.FormatFloat(f, fmt, prec, bitSize)
+}
+
+// AppendFloat appends the string form of the floating-point number f,
+// as generated by [FormatFloat], to dst and returns the extended buffer.
+func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte {
+ return strconv.AppendFloat(dst, f, fmt, prec, bitSize)
+}
+
+// FormatUint returns the string representation of i in the given base,
+// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
+// for digit values >= 10.
+func FormatUint(i uint64, base int) string {
+ return strconv.FormatUint(i, base)
+}
+
+// FormatInt returns the string representation of i in the given base,
+// for 2 <= base <= 36. The result uses the lower-case letters 'a' to 'z'
+// for digit values >= 10.
+func FormatInt(i int64, base int) string {
+ return strconv.FormatInt(i, base)
+}
+
+// Itoa is equivalent to [FormatInt](int64(i), 10).
+func Itoa(i int) string {
+ return strconv.Itoa(i)
+}
+
+// AppendInt appends the string form of the integer i,
+// as generated by [FormatInt], to dst and returns the extended buffer.
+func AppendInt(dst []byte, i int64, base int) []byte {
+ return strconv.AppendInt(dst, i, base)
+}
+
+// AppendUint appends the string form of the unsigned integer i,
+// as generated by [FormatUint], to dst and returns the extended buffer.
+func AppendUint(dst []byte, i uint64, base int) []byte {
+ return strconv.AppendUint(dst, i, base)
+}
+
+// toError converts from internal/strconv.Error to the error guaranteed by this package's APIs.
+func toError(fn, s string, base, bitSize int, err error) error {
+ switch err {
+ case strconv.ErrSyntax:
+ return syntaxError(fn, s)
+ case strconv.ErrRange:
+ return rangeError(fn, s)
+ case strconv.ErrBase:
+ return baseError(fn, s, base)
+ case strconv.ErrBitSize:
+ return bitSizeError(fn, s, bitSize)
+ }
+ return err
+}
+
+// ErrRange indicates that a value is out of range for the target type.
+var ErrRange = errors.New("value out of range")
+
+// ErrSyntax indicates that a value does not have the right syntax for the target type.
+var ErrSyntax = errors.New("invalid syntax")
+
+// A NumError records a failed conversion.
+type NumError struct {
+ Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat, ParseComplex)
+ Num string // the input
+ Err error // the reason the conversion failed (e.g. ErrRange, ErrSyntax, etc.)
+}
+
+func (e *NumError) Error() string {
+ return "strconv." + e.Func + ": " + "parsing " + Quote(e.Num) + ": " + e.Err.Error()
+}
+
+func (e *NumError) Unwrap() error { return e.Err }
+
+// All ParseXXX functions allow the input string to escape to the error value.
+// This hurts strconv.ParseXXX(string(b)) calls where b is []byte since
+// the conversion from []byte must allocate a string on the heap.
+// If we assume errors are infrequent, then we can avoid escaping the input
+// back to the output by copying it first. This allows the compiler to call
+// strconv.ParseXXX without a heap allocation for most []byte to string
+// conversions, since it can now prove that the string cannot escape Parse.
+
+func syntaxError(fn, str string) *NumError {
+ return &NumError{fn, stringslite.Clone(str), ErrSyntax}
+}
+
+func rangeError(fn, str string) *NumError {
+ return &NumError{fn, stringslite.Clone(str), ErrRange}
+}
+
+func baseError(fn, str string, base int) *NumError {
+ return &NumError{fn, stringslite.Clone(str), errors.New("invalid base " + Itoa(base))}
+}
+
+func bitSizeError(fn, str string, bitSize int) *NumError {
+ return &NumError{fn, stringslite.Clone(str), errors.New("invalid bit size " + Itoa(bitSize))}
+}
diff --git a/src/strconv/number_test.go b/src/strconv/number_test.go
new file mode 100644
index 0000000000..4408bc0556
--- /dev/null
+++ b/src/strconv/number_test.go
@@ -0,0 +1,956 @@
+// 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.
+
+// Note: These tests are focused mainly on generating the right errors.
+// The extensive numerical tests are in ../internal/strconv.
+// Add new tests there instead of here whenever possible.
+
+package strconv_test
+
+import (
+ "bytes"
+ "errors"
+ "math"
+ "math/cmplx"
+ "reflect"
+ . "strconv"
+ "testing"
+)
+
+type atobTest struct {
+ in string
+ out bool
+ err error
+}
+
+var atobtests = []atobTest{
+ {"", false, ErrSyntax},
+ {"asdf", false, ErrSyntax},
+ {"0", false, nil},
+ {"false", false, nil},
+ {"true", true, nil},
+}
+
+func TestParseBool(t *testing.T) {
+ for _, test := range atobtests {
+ b, e := ParseBool(test.in)
+ if test.err != nil {
+ // expect an error
+ if e == nil {
+ t.Errorf("ParseBool(%s) = nil; want %s", test.in, test.err)
+ } else {
+ // NumError assertion must succeed; it's the only thing we return.
+ if e.(*NumError).Err != test.err {
+ t.Errorf("ParseBool(%s) = %s; want %s", test.in, e, test.err)
+ }
+ }
+ } else {
+ if e != nil {
+ t.Errorf("ParseBool(%s) = %s; want nil", test.in, e)
+ }
+ if b != test.out {
+ t.Errorf("ParseBool(%s) = %t; want %t", test.in, b, test.out)
+ }
+ }
+ }
+}
+
+var boolString = map[bool]string{
+ true: "true",
+ false: "false",
+}
+
+func TestFormatBool(t *testing.T) {
+ for b, s := range boolString {
+ if f := FormatBool(b); f != s {
+ t.Errorf("FormatBool(%v) = %q; want %q", b, f, s)
+ }
+ }
+}
+
+type appendBoolTest struct {
+ b bool
+ in []byte
+ out []byte
+}
+
+var appendBoolTests = []appendBoolTest{
+ {true, []byte("foo "), []byte("foo true")},
+ {false, []byte("foo "), []byte("foo false")},
+}
+
+func TestAppendBool(t *testing.T) {
+ for _, test := range appendBoolTests {
+ b := AppendBool(test.in, test.b)
+ if !bytes.Equal(b, test.out) {
+ t.Errorf("AppendBool(%q, %v) = %q; want %q", test.in, test.b, b, test.out)
+ }
+ }
+}
+
+var (
+ infp0 = complex(math.Inf(+1), 0)
+ infm0 = complex(math.Inf(-1), 0)
+ inf0p = complex(0, math.Inf(+1))
+ inf0m = complex(0, math.Inf(-1))
+
+ infpp = complex(math.Inf(+1), math.Inf(+1))
+ infpm = complex(math.Inf(+1), math.Inf(-1))
+ infmp = complex(math.Inf(-1), math.Inf(+1))
+ infmm = complex(math.Inf(-1), math.Inf(-1))
+)
+
+type atocTest struct {
+ in string
+ out complex128
+ err error
+}
+
+func TestParseComplex(t *testing.T) {
+ tests := []atocTest{
+ // Clearly invalid
+ {"", 0, ErrSyntax},
+ {" ", 0, ErrSyntax},
+ {"(", 0, ErrSyntax},
+ {")", 0, ErrSyntax},
+ {"i", 0, ErrSyntax},
+ {"+i", 0, ErrSyntax},
+ {"-i", 0, ErrSyntax},
+ {"1I", 0, ErrSyntax},
+ {"10 + 5i", 0, ErrSyntax},
+ {"3+", 0, ErrSyntax},
+ {"3+5", 0, ErrSyntax},
+ {"3+5+5i", 0, ErrSyntax},
+
+ // Parentheses
+ {"()", 0, ErrSyntax},
+ {"(i)", 0, ErrSyntax},
+ {"(0)", 0, nil},
+ {"(1i)", 1i, nil},
+ {"(3.0+5.5i)", 3.0 + 5.5i, nil},
+ {"(1)+1i", 0, ErrSyntax},
+ {"(3.0+5.5i", 0, ErrSyntax},
+ {"3.0+5.5i)", 0, ErrSyntax},
+
+ // NaNs
+ {"NaN", complex(math.NaN(), 0), nil},
+ {"NANi", complex(0, math.NaN()), nil},
+ {"nan+nAni", complex(math.NaN(), math.NaN()), nil},
+ {"+NaN", 0, ErrSyntax},
+ {"-NaN", 0, ErrSyntax},
+ {"NaN-NaNi", 0, ErrSyntax},
+
+ // Infs
+ {"Inf", infp0, nil},
+ {"+inf", infp0, nil},
+ {"-inf", infm0, nil},
+ {"Infinity", infp0, nil},
+ {"+INFINITY", infp0, nil},
+ {"-infinity", infm0, nil},
+ {"+infi", inf0p, nil},
+ {"0-infinityi", inf0m, nil},
+ {"Inf+Infi", infpp, nil},
+ {"+Inf-Infi", infpm, nil},
+ {"-Infinity+Infi", infmp, nil},
+ {"inf-inf", 0, ErrSyntax},
+
+ // Zeros
+ {"0", 0, nil},
+ {"0i", 0, nil},
+ {"-0.0i", 0, nil},
+ {"0+0.0i", 0, nil},
+ {"0e+0i", 0, nil},
+ {"0e-0+0i", 0, nil},
+ {"-0.0-0.0i", 0, nil},
+ {"0e+012345", 0, nil},
+ {"0x0p+012345i", 0, nil},
+ {"0x0.00p-012345i", 0, nil},
+ {"+0e-0+0e-0i", 0, nil},
+ {"0e+0+0e+0i", 0, nil},
+ {"-0e+0-0e+0i", 0, nil},
+
+ // Regular non-zeroes
+ {"0.1", 0.1, nil},
+ {"0.1i", 0 + 0.1i, nil},
+ {"0.123", 0.123, nil},
+ {"0.123i", 0 + 0.123i, nil},
+ {"0.123+0.123i", 0.123 + 0.123i, nil},
+ {"99", 99, nil},
+ {"+99", 99, nil},
+ {"-99", -99, nil},
+ {"+1i", 1i, nil},
+ {"-1i", -1i, nil},
+ {"+3+1i", 3 + 1i, nil},
+ {"30+3i", 30 + 3i, nil},
+ {"+3e+3-3e+3i", 3e+3 - 3e+3i, nil},
+ {"+3e+3+3e+3i", 3e+3 + 3e+3i, nil},
+ {"+3e+3+3e+3i+", 0, ErrSyntax},
+
+ // Separators
+ {"0.1", 0.1, nil},
+ {"0.1i", 0 + 0.1i, nil},
+ {"0.1_2_3", 0.123, nil},
+ {"+0x_3p3i", 0x3p3i, nil},
+ {"0_0+0x_0p0i", 0, nil},
+ {"0x_10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
+ {"+0x_1_0.3p-8+0x_3_0p3i", 0x10.3p-8 + 0x30p3i, nil},
+ {"0x1_0.3p+8-0x_3p3i", 0x10.3p+8 - 0x3p3i, nil},
+
+ // Hexadecimals
+ {"0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
+ {"+0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
+ {"0x10.3p+8-0x3p3i", 0x10.3p+8 - 0x3p3i, nil},
+ {"0x1p0", 1, nil},
+ {"0x1p1", 2, nil},
+ {"0x1p-1", 0.5, nil},
+ {"0x1ep-1", 15, nil},
+ {"-0x1ep-1", -15, nil},
+ {"-0x2p3", -16, nil},
+ {"0x1e2", 0, ErrSyntax},
+ {"1p2", 0, ErrSyntax},
+ {"0x1e2i", 0, ErrSyntax},
+
+ // ErrRange
+ // next float64 - too large
+ {"+0x1p1024", infp0, ErrRange},
+ {"-0x1p1024", infm0, ErrRange},
+ {"+0x1p1024i", inf0p, ErrRange},
+ {"-0x1p1024i", inf0m, ErrRange},
+ {"+0x1p1024+0x1p1024i", infpp, ErrRange},
+ {"+0x1p1024-0x1p1024i", infpm, ErrRange},
+ {"-0x1p1024+0x1p1024i", infmp, ErrRange},
+ {"-0x1p1024-0x1p1024i", infmm, ErrRange},
+ // the border is ...158079
+ // borderline - okay
+ {"+0x1.fffffffffffff7fffp1023+0x1.fffffffffffff7fffp1023i", 1.7976931348623157e+308 + 1.7976931348623157e+308i, nil},
+ {"+0x1.fffffffffffff7fffp1023-0x1.fffffffffffff7fffp1023i", 1.7976931348623157e+308 - 1.7976931348623157e+308i, nil},
+ {"-0x1.fffffffffffff7fffp1023+0x1.fffffffffffff7fffp1023i", -1.7976931348623157e+308 + 1.7976931348623157e+308i, nil},
+ {"-0x1.fffffffffffff7fffp1023-0x1.fffffffffffff7fffp1023i", -1.7976931348623157e+308 - 1.7976931348623157e+308i, nil},
+ // borderline - too large
+ {"+0x1.fffffffffffff8p1023", infp0, ErrRange},
+ {"-0x1fffffffffffff.8p+971", infm0, ErrRange},
+ {"+0x1.fffffffffffff8p1023i", inf0p, ErrRange},
+ {"-0x1fffffffffffff.8p+971i", inf0m, ErrRange},
+ {"+0x1.fffffffffffff8p1023+0x1.fffffffffffff8p1023i", infpp, ErrRange},
+ {"+0x1.fffffffffffff8p1023-0x1.fffffffffffff8p1023i", infpm, ErrRange},
+ {"-0x1fffffffffffff.8p+971+0x1fffffffffffff.8p+971i", infmp, ErrRange},
+ {"-0x1fffffffffffff8p+967-0x1fffffffffffff8p+967i", infmm, ErrRange},
+ // a little too large
+ {"1e308+1e308i", 1e+308 + 1e+308i, nil},
+ {"2e308+2e308i", infpp, ErrRange},
+ {"1e309+1e309i", infpp, ErrRange},
+ {"0x1p1025+0x1p1025i", infpp, ErrRange},
+ {"2e308", infp0, ErrRange},
+ {"1e309", infp0, ErrRange},
+ {"0x1p1025", infp0, ErrRange},
+ {"2e308i", inf0p, ErrRange},
+ {"1e309i", inf0p, ErrRange},
+ {"0x1p1025i", inf0p, ErrRange},
+ // way too large
+ {"+1e310+1e310i", infpp, ErrRange},
+ {"+1e310-1e310i", infpm, ErrRange},
+ {"-1e310+1e310i", infmp, ErrRange},
+ {"-1e310-1e310i", infmm, ErrRange},
+ // under/overflow exponent
+ {"1e-4294967296", 0, nil},
+ {"1e-4294967296i", 0, nil},
+ {"1e-4294967296+1i", 1i, nil},
+ {"1+1e-4294967296i", 1, nil},
+ {"1e-4294967296+1e-4294967296i", 0, nil},
+ {"1e+4294967296", infp0, ErrRange},
+ {"1e+4294967296i", inf0p, ErrRange},
+ {"1e+4294967296+1e+4294967296i", infpp, ErrRange},
+ {"1e+4294967296-1e+4294967296i", infpm, ErrRange},
+ }
+ for i := range tests {
+ test := &tests[i]
+ if test.err != nil {
+ test.err = &NumError{Func: "ParseComplex", Num: test.in, Err: test.err}
+ }
+ got, err := ParseComplex(test.in, 128)
+ if !reflect.DeepEqual(err, test.err) {
+ t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
+ }
+ if !(cmplx.IsNaN(test.out) && cmplx.IsNaN(got)) && got != test.out {
+ t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
+ }
+
+ if complex128(complex64(test.out)) == test.out {
+ got, err := ParseComplex(test.in, 64)
+ if !reflect.DeepEqual(err, test.err) {
+ t.Fatalf("ParseComplex(%q, 64) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
+ }
+ got64 := complex64(got)
+ if complex128(got64) != test.out {
+ t.Fatalf("ParseComplex(%q, 64) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
+ }
+ }
+ }
+}
+
+// Issue 42297: allow ParseComplex(s, not_32_or_64) for legacy reasons
+func TestParseComplexIncorrectBitSize(t *testing.T) {
+ const s = "1.5e308+1.0e307i"
+ const want = 1.5e308 + 1.0e307i
+
+ for _, bitSize := range []int{0, 10, 100, 256} {
+ c, err := ParseComplex(s, bitSize)
+ if err != nil {
+ t.Fatalf("ParseComplex(%q, %d) gave error %s", s, bitSize, err)
+ }
+ if c != want {
+ t.Fatalf("ParseComplex(%q, %d) = %g (expected %g)", s, bitSize, c, want)
+ }
+ }
+}
+
+type atofTest struct {
+ in string
+ out string
+ err error
+}
+
+var atoftests = []atofTest{
+ {"", "0", ErrSyntax},
+ {"1.25", "1.25", nil},
+ {"+1", "1", nil},
+ {"1x", "0", ErrSyntax},
+ {"1.1.", "0", ErrSyntax},
+ {"1e23", "1e+23", nil},
+ {"1E23", "1e+23", nil},
+ {"0x1fFe2.p0", "131042", nil},
+ {"0x1fFe2.P0", "131042", nil},
+ {"-0x2p3", "-16", nil},
+ {"0x0.fp4", "15", nil},
+ {"0x0.fp0", "0.9375", nil},
+ {"0x1e2", "0", ErrSyntax},
+ {"1p2", "0", ErrSyntax},
+ {"0x1p1024", "+Inf", ErrRange},
+ {"-0x1p1024", "-Inf", ErrRange},
+ {"0x1.fffffffffffff7fffp1023", "1.7976931348623157e+308", nil},
+ {"-0x1.fffffffffffff7fffp1023", "-1.7976931348623157e+308", nil},
+ {"1.797693134862315808e308", "+Inf", ErrRange},
+ {"-1.797693134862315808e308", "-Inf", ErrRange},
+}
+
+func init() {
+ // The atof routines return NumErrors wrapping
+ // the error and the string. Convert the table above.
+ for i := range atoftests {
+ test := &atoftests[i]
+ if test.err != nil {
+ test.err = &NumError{"ParseFloat", test.in, test.err}
+ }
+ }
+}
+
+func TestAtof(t *testing.T) {
+ for i := 0; i < len(atoftests); i++ {
+ test := &atoftests[i]
+ out, err := ParseFloat(test.in, 64)
+ outs := FormatFloat(out, 'g', -1, 64)
+ if outs != test.out || !reflect.DeepEqual(err, test.err) {
+ t.Errorf("ParseFloat(%v, 64) = %v, %v want %v, %v",
+ test.in, out, err, test.out, test.err)
+ }
+
+ if float64(float32(out)) == out {
+ out, err := ParseFloat(test.in, 32)
+ out32 := float32(out)
+ if float64(out32) != out {
+ t.Errorf("ParseFloat(%v, 32) = %v, not a float32 (closest is %v)", test.in, out, float64(out32))
+ continue
+ }
+ outs := FormatFloat(float64(out32), 'g', -1, 32)
+ if outs != test.out || !reflect.DeepEqual(err, test.err) {
+ t.Errorf("ParseFloat(%v, 32) = %v, %v want %v, %v # %v",
+ test.in, out32, err, test.out, test.err, out)
+ }
+ }
+ }
+}
+
+type parseUint64Test struct {
+ in string
+ out uint64
+ err error
+}
+
+var parseUint64Tests = []parseUint64Test{
+ {"", 0, ErrSyntax},
+ {"0", 0, nil},
+ {"1", 1, nil},
+ {"12345", 12345, nil},
+ {"012345", 12345, nil},
+ {"18446744073709551616", 1<<64 - 1, ErrRange},
+ {"-1", 0, ErrSyntax},
+}
+
+type parseUint64BaseTest struct {
+ in string
+ base int
+ out uint64
+ err error
+}
+
+var parseUint64BaseTests = []parseUint64BaseTest{
+ {"", 0, 0, ErrSyntax},
+ {"0", 0, 0, nil},
+ {"1", 0, 1, nil},
+ {"-1", 0, 0, ErrSyntax},
+ {"12345", 0, 12345, nil},
+ {"012345", 0, 012345, nil},
+ {"18446744073709551616", 0, 1<<64 - 1, ErrRange},
+ {"0b", 0, 0, ErrSyntax},
+ {"101", 2, 5, nil},
+ {"101_", 2, 0, ErrSyntax},
+}
+
+type parseInt64Test struct {
+ in string
+ out int64
+ err error
+}
+
+var parseInt64Tests = []parseInt64Test{
+ {"", 0, ErrSyntax},
+ {"0", 0, nil},
+ {"1", 1, nil},
+ {"-1", -1, nil},
+ {"12345", 12345, nil},
+ {"9223372036854775808", 1<<63 - 1, ErrRange},
+ {"123%45", 0, ErrSyntax},
+}
+
+type parseInt64BaseTest struct {
+ in string
+ base int
+ out int64
+ err error
+}
+
+var parseInt64BaseTests = []parseInt64BaseTest{
+ {"", 0, 0, ErrSyntax},
+ {"0", 0, 0, nil},
+ {"1", 0, 1, nil},
+ {"-1", 0, -1, nil},
+ {"12345", 0, 12345, nil},
+ {"12345", 9, 8303, nil},
+ {"012345", 0, 012345, nil},
+ {"9223372036854775808", 10, 1<<63 - 1, ErrRange},
+ {"0b", 0, 0, ErrSyntax},
+ {"101", 2, 5, nil},
+ {"101_", 2, 0, ErrSyntax},
+}
+
+type parseUint32Test struct {
+ in string
+ out uint32
+ err error
+}
+
+var parseUint32Tests = []parseUint32Test{
+ {"", 0, ErrSyntax},
+ {"0", 0, nil},
+ {"1", 1, nil},
+ {"12345", 12345, nil},
+ {"12345x", 0, ErrSyntax},
+ {"987654321", 987654321, nil},
+ {"4294967296", 1<<32 - 1, ErrRange},
+ {"1_2_3_4_5", 0, ErrSyntax}, // base=10 so no underscores allowed
+ {"12345_", 0, ErrSyntax},
+}
+
+type parseInt32Test struct {
+ in string
+ out int32
+ err error
+}
+
+var parseInt32Tests = []parseInt32Test{
+ {"", 0, ErrSyntax},
+ {"0", 0, nil},
+ {"-0", 0, nil},
+ {"1", 1, nil},
+ {"-1", -1, nil},
+ {"12345", 12345, nil},
+ {"-12345", -12345, nil},
+ {"2147483648", 1<<31 - 1, ErrRange},
+ {"12345_", 0, ErrSyntax},
+}
+
+type numErrorTest struct {
+ num, want string
+}
+
+var numErrorTests = []numErrorTest{
+ {"0", `strconv.ParseFloat: parsing "0": failed`},
+ {"`", "strconv.ParseFloat: parsing \"`\": failed"},
+ {"1\x00.2", `strconv.ParseFloat: parsing "1\x00.2": failed`},
+}
+
+func init() {
+ // The parse routines return NumErrors wrapping
+ // the error and the string. Convert the tables above.
+ for i := range parseUint64Tests {
+ test := &parseUint64Tests[i]
+ if test.err != nil {
+ test.err = &NumError{"ParseUint", test.in, test.err}
+ }
+ }
+ for i := range parseUint64BaseTests {
+ test := &parseUint64BaseTests[i]
+ if test.err != nil {
+ test.err = &NumError{"ParseUint", test.in, test.err}
+ }
+ }
+ for i := range parseInt64Tests {
+ test := &parseInt64Tests[i]
+ if test.err != nil {
+ test.err = &NumError{"ParseInt", test.in, test.err}
+ }
+ }
+ for i := range parseInt64BaseTests {
+ test := &parseInt64BaseTests[i]
+ if test.err != nil {
+ test.err = &NumError{"ParseInt", test.in, test.err}
+ }
+ }
+ for i := range parseUint32Tests {
+ test := &parseUint32Tests[i]
+ if test.err != nil {
+ test.err = &NumError{"ParseUint", test.in, test.err}
+ }
+ }
+ for i := range parseInt32Tests {
+ test := &parseInt32Tests[i]
+ if test.err != nil {
+ test.err = &NumError{"ParseInt", test.in, test.err}
+ }
+ }
+}
+
+func TestParseUint32(t *testing.T) {
+ for i := range parseUint32Tests {
+ test := &parseUint32Tests[i]
+ out, err := ParseUint(test.in, 10, 32)
+ if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseUint(%q, 10, 32) = %v, %v want %v, %v",
+ test.in, out, err, test.out, test.err)
+ }
+ }
+}
+
+func TestParseUint64(t *testing.T) {
+ for i := range parseUint64Tests {
+ test := &parseUint64Tests[i]
+ out, err := ParseUint(test.in, 10, 64)
+ if test.out != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseUint(%q, 10, 64) = %v, %v want %v, %v",
+ test.in, out, err, test.out, test.err)
+ }
+ }
+}
+
+func TestParseUint64Base(t *testing.T) {
+ for i := range parseUint64BaseTests {
+ test := &parseUint64BaseTests[i]
+ out, err := ParseUint(test.in, test.base, 64)
+ if test.out != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseUint(%q, %v, 64) = %v, %v want %v, %v",
+ test.in, test.base, out, err, test.out, test.err)
+ }
+ }
+}
+
+func TestParseInt32(t *testing.T) {
+ for i := range parseInt32Tests {
+ test := &parseInt32Tests[i]
+ out, err := ParseInt(test.in, 10, 32)
+ if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseInt(%q, 10 ,32) = %v, %v want %v, %v",
+ test.in, out, err, test.out, test.err)
+ }
+ }
+}
+
+func TestParseInt64(t *testing.T) {
+ for i := range parseInt64Tests {
+ test := &parseInt64Tests[i]
+ out, err := ParseInt(test.in, 10, 64)
+ if test.out != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseInt(%q, 10, 64) = %v, %v want %v, %v",
+ test.in, out, err, test.out, test.err)
+ }
+ }
+}
+
+func TestParseInt64Base(t *testing.T) {
+ for i := range parseInt64BaseTests {
+ test := &parseInt64BaseTests[i]
+ out, err := ParseInt(test.in, test.base, 64)
+ if test.out != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseInt(%q, %v, 64) = %v, %v want %v, %v",
+ test.in, test.base, out, err, test.out, test.err)
+ }
+ }
+}
+
+func TestParseUint(t *testing.T) {
+ switch IntSize {
+ case 32:
+ for i := range parseUint32Tests {
+ test := &parseUint32Tests[i]
+ out, err := ParseUint(test.in, 10, 0)
+ if uint64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
+ test.in, out, err, test.out, test.err)
+ }
+ }
+ case 64:
+ for i := range parseUint64Tests {
+ test := &parseUint64Tests[i]
+ out, err := ParseUint(test.in, 10, 0)
+ if test.out != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseUint(%q, 10, 0) = %v, %v want %v, %v",
+ test.in, out, err, test.out, test.err)
+ }
+ }
+ }
+}
+
+func TestParseInt(t *testing.T) {
+ switch IntSize {
+ case 32:
+ for i := range parseInt32Tests {
+ test := &parseInt32Tests[i]
+ out, err := ParseInt(test.in, 10, 0)
+ if int64(test.out) != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
+ test.in, out, err, test.out, test.err)
+ }
+ }
+ case 64:
+ for i := range parseInt64Tests {
+ test := &parseInt64Tests[i]
+ out, err := ParseInt(test.in, 10, 0)
+ if test.out != out || !reflect.DeepEqual(test.err, err) {
+ t.Errorf("ParseInt(%q, 10, 0) = %v, %v want %v, %v",
+ test.in, out, err, test.out, test.err)
+ }
+ }
+ }
+}
+
+func TestAtoi(t *testing.T) {
+ switch IntSize {
+ case 32:
+ for i := range parseInt32Tests {
+ test := &parseInt32Tests[i]
+ out, err := Atoi(test.in)
+ var testErr error
+ if test.err != nil {
+ testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
+ }
+ if int(test.out) != out || !reflect.DeepEqual(testErr, err) {
+ t.Errorf("Atoi(%q) = %v, %v want %v, %v",
+ test.in, out, err, test.out, testErr)
+ }
+ }
+ case 64:
+ for i := range parseInt64Tests {
+ test := &parseInt64Tests[i]
+ out, err := Atoi(test.in)
+ var testErr error
+ if test.err != nil {
+ testErr = &NumError{"Atoi", test.in, test.err.(*NumError).Err}
+ }
+ if test.out != int64(out) || !reflect.DeepEqual(testErr, err) {
+ t.Errorf("Atoi(%q) = %v, %v want %v, %v",
+ test.in, out, err, test.out, testErr)
+ }
+ }
+ }
+}
+
+func bitSizeErrStub(name string, bitSize int) error {
+ return bitSizeError(name, "0", bitSize)
+}
+
+func baseErrStub(name string, base int) error {
+ return baseError(name, "0", base)
+}
+
+func noErrStub(name string, arg int) error {
+ return nil
+}
+
+type parseErrorTest struct {
+ arg int
+ errStub func(name string, arg int) error
+}
+
+var parseBitSizeTests = []parseErrorTest{
+ {-1, bitSizeErrStub},
+ {0, noErrStub},
+ {64, noErrStub},
+ {65, bitSizeErrStub},
+}
+
+var parseBaseTests = []parseErrorTest{
+ {-1, baseErrStub},
+ {0, noErrStub},
+ {1, baseErrStub},
+ {2, noErrStub},
+ {36, noErrStub},
+ {37, baseErrStub},
+}
+
+func equalError(a, b error) bool {
+ if a == nil {
+ return b == nil
+ }
+ if b == nil {
+ return a == nil
+ }
+ return a.Error() == b.Error()
+}
+
+func TestParseIntBitSize(t *testing.T) {
+ for i := range parseBitSizeTests {
+ test := &parseBitSizeTests[i]
+ testErr := test.errStub("ParseInt", test.arg)
+ _, err := ParseInt("0", 0, test.arg)
+ if !equalError(testErr, err) {
+ t.Errorf("ParseInt(\"0\", 0, %v) = 0, %v want 0, %v",
+ test.arg, err, testErr)
+ }
+ }
+}
+
+func TestParseUintBitSize(t *testing.T) {
+ for i := range parseBitSizeTests {
+ test := &parseBitSizeTests[i]
+ testErr := test.errStub("ParseUint", test.arg)
+ _, err := ParseUint("0", 0, test.arg)
+ if !equalError(testErr, err) {
+ t.Errorf("ParseUint(\"0\", 0, %v) = 0, %v want 0, %v",
+ test.arg, err, testErr)
+ }
+ }
+}
+
+func TestParseIntBase(t *testing.T) {
+ for i := range parseBaseTests {
+ test := &parseBaseTests[i]
+ testErr := test.errStub("ParseInt", test.arg)
+ _, err := ParseInt("0", test.arg, 0)
+ if !equalError(testErr, err) {
+ t.Errorf("ParseInt(\"0\", %v, 0) = 0, %v want 0, %v",
+ test.arg, err, testErr)
+ }
+ }
+}
+
+func TestParseUintBase(t *testing.T) {
+ for i := range parseBaseTests {
+ test := &parseBaseTests[i]
+ testErr := test.errStub("ParseUint", test.arg)
+ _, err := ParseUint("0", test.arg, 0)
+ if !equalError(testErr, err) {
+ t.Errorf("ParseUint(\"0\", %v, 0) = 0, %v want 0, %v",
+ test.arg, err, testErr)
+ }
+ }
+}
+
+func TestNumError(t *testing.T) {
+ for _, test := range numErrorTests {
+ err := &NumError{
+ Func: "ParseFloat",
+ Num: test.num,
+ Err: errors.New("failed"),
+ }
+ if got := err.Error(); got != test.want {
+ t.Errorf(`(&NumError{"ParseFloat", %q, "failed"}).Error() = %v, want %v`, test.num, got, test.want)
+ }
+ }
+}
+
+func TestNumErrorUnwrap(t *testing.T) {
+ err := &NumError{Err: ErrSyntax}
+ if !errors.Is(err, ErrSyntax) {
+ t.Error("errors.Is failed, wanted success")
+ }
+}
+
+func TestFormatComplex(t *testing.T) {
+ tests := []struct {
+ c complex128
+ fmt byte
+ prec int
+ bitSize int
+ out string
+ }{
+ // a variety of signs
+ {1 + 2i, 'g', -1, 128, "(1+2i)"},
+ {3 - 4i, 'g', -1, 128, "(3-4i)"},
+ {-5 + 6i, 'g', -1, 128, "(-5+6i)"},
+ {-7 - 8i, 'g', -1, 128, "(-7-8i)"},
+
+ // test that fmt and prec are working
+ {3.14159 + 0.00123i, 'e', 3, 128, "(3.142e+00+1.230e-03i)"},
+ {3.14159 + 0.00123i, 'f', 3, 128, "(3.142+0.001i)"},
+ {3.14159 + 0.00123i, 'g', 3, 128, "(3.14+0.00123i)"},
+
+ // ensure bitSize rounding is working
+ {1.2345678901234567 + 9.876543210987654i, 'f', -1, 128, "(1.2345678901234567+9.876543210987654i)"},
+ {1.2345678901234567 + 9.876543210987654i, 'f', -1, 64, "(1.2345679+9.876543i)"},
+
+ // other cases are handled by FormatFloat tests
+ }
+ for _, test := range tests {
+ out := FormatComplex(test.c, test.fmt, test.prec, test.bitSize)
+ if out != test.out {
+ t.Fatalf("FormatComplex(%v, %q, %d, %d) = %q; want %q",
+ test.c, test.fmt, test.prec, test.bitSize, out, test.out)
+ }
+ }
+}
+
+func TestFormatComplexInvalidBitSize(t *testing.T) {
+ defer func() {
+ if r := recover(); r == nil {
+ t.Fatalf("expected panic due to invalid bitSize")
+ }
+ }()
+ _ = FormatComplex(1+2i, 'g', -1, 100)
+}
+
+type itob64Test struct {
+ in int64
+ base int
+ out string
+}
+
+var itob64tests = []itob64Test{
+ {0, 10, "0"},
+ {1, 10, "1"},
+ {-1, 10, "-1"},
+ {12345678, 10, "12345678"},
+ {-1 << 63, 10, "-9223372036854775808"},
+ {16, 17, "g"},
+ {25, 25, "10"},
+ {(((((17*36+24)*36+21)*36+34)*36+12)*36+24)*36 + 32, 36, "holycow"},
+}
+
+func TestItoa(t *testing.T) {
+ for _, test := range itob64tests {
+ s := FormatInt(test.in, test.base)
+ if s != test.out {
+ t.Errorf("FormatInt(%v, %v) = %v want %v",
+ test.in, test.base, s, test.out)
+ }
+ x := AppendInt([]byte("abc"), test.in, test.base)
+ if string(x) != "abc"+test.out {
+ t.Errorf("AppendInt(%q, %v, %v) = %q want %v",
+ "abc", test.in, test.base, x, test.out)
+ }
+
+ if test.in >= 0 {
+ s := FormatUint(uint64(test.in), test.base)
+ if s != test.out {
+ t.Errorf("FormatUint(%v, %v) = %v want %v",
+ test.in, test.base, s, test.out)
+ }
+ x := AppendUint(nil, uint64(test.in), test.base)
+ if string(x) != test.out {
+ t.Errorf("AppendUint(%q, %v, %v) = %q want %v",
+ "abc", uint64(test.in), test.base, x, test.out)
+ }
+ }
+
+ if test.base == 10 && int64(int(test.in)) == test.in {
+ s := Itoa(int(test.in))
+ if s != test.out {
+ t.Errorf("Itoa(%v) = %v want %v",
+ test.in, s, test.out)
+ }
+ }
+ }
+
+ // Override when base is illegal
+ defer func() {
+ if r := recover(); r == nil {
+ t.Fatalf("expected panic due to illegal base")
+ }
+ }()
+ FormatUint(12345678, 1)
+}
+
+type uitob64Test struct {
+ in uint64
+ base int
+ out string
+}
+
+var uitob64tests = []uitob64Test{
+ {1<<63 - 1, 10, "9223372036854775807"},
+ {1 << 63, 10, "9223372036854775808"},
+ {1<<63 + 1, 10, "9223372036854775809"},
+ {1<<64 - 2, 10, "18446744073709551614"},
+ {1<<64 - 1, 10, "18446744073709551615"},
+ {1<<64 - 1, 2, "1111111111111111111111111111111111111111111111111111111111111111"},
+}
+
+func TestUitoa(t *testing.T) {
+ for _, test := range uitob64tests {
+ s := FormatUint(test.in, test.base)
+ if s != test.out {
+ t.Errorf("FormatUint(%v, %v) = %v want %v",
+ test.in, test.base, s, test.out)
+ }
+ x := AppendUint([]byte("abc"), test.in, test.base)
+ if string(x) != "abc"+test.out {
+ t.Errorf("AppendUint(%q, %v, %v) = %q want %v",
+ "abc", test.in, test.base, x, test.out)
+ }
+
+ }
+}
+
+var varlenUints = []struct {
+ in uint64
+ out string
+}{
+ {1, "1"},
+ {12, "12"},
+ {123, "123"},
+ {1234, "1234"},
+ {12345, "12345"},
+ {123456, "123456"},
+ {1234567, "1234567"},
+ {12345678, "12345678"},
+ {123456789, "123456789"},
+ {1234567890, "1234567890"},
+ {12345678901, "12345678901"},
+ {123456789012, "123456789012"},
+ {1234567890123, "1234567890123"},
+ {12345678901234, "12345678901234"},
+ {123456789012345, "123456789012345"},
+ {1234567890123456, "1234567890123456"},
+ {12345678901234567, "12345678901234567"},
+ {123456789012345678, "123456789012345678"},
+ {1234567890123456789, "1234567890123456789"},
+ {12345678901234567890, "12345678901234567890"},
+}
+
+func TestFormatUintVarlen(t *testing.T) {
+ for _, test := range varlenUints {
+ s := FormatUint(test.in, 10)
+ if s != test.out {
+ t.Errorf("FormatUint(%v, 10) = %v want %v", test.in, s, test.out)
+ }
+ }
+}
diff --git a/src/strconv/pow10gen.go b/src/strconv/pow10gen.go
deleted file mode 100644
index 2d428fe088..0000000000
--- a/src/strconv/pow10gen.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2025 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.
-
-//go:build ignore
-
-package main
-
-import (
- "bytes"
- "fmt"
- "go/format"
- "log"
- "math/big"
- "os"
-)
-
-const (
- minExp = -348
- maxExp = 347
-)
-
-func main() {
- log.SetPrefix("pow10gen: ")
- log.SetFlags(0)
-
- var (
- one = big.NewInt(1)
- ten = big.NewInt(10)
-
- b1p64 = new(big.Int).Lsh(one, 64)
- b1p128 = new(big.Int).Lsh(one, 128)
-
- r2 = big.NewRat(2, 1)
- r1p128 = new(big.Rat).SetInt(b1p128)
- )
-
- var out bytes.Buffer
- fmt.Fprintf(&out, top, minExp, maxExp)
- for e := int64(minExp); e <= maxExp; e++ {
- var r *big.Rat
- if e >= 0 {
- r = new(big.Rat).SetInt(new(big.Int).Exp(ten, big.NewInt(e), nil))
- } else {
- r = new(big.Rat).SetFrac(one, new(big.Int).Exp(ten, big.NewInt(-e), nil))
- }
- be := 0
- for r.Cmp(r1p128) < 0 {
- r.Mul(r, r2)
- be++
- }
- for r.Cmp(r1p128) >= 0 {
- r.Quo(r, r2)
- be--
- }
- d := new(big.Int).Div(r.Num(), r.Denom())
- hi, lo := new(big.Int).DivMod(d, b1p64, new(big.Int))
- fmt.Fprintf(&out, "\t{%#016x, %#016x}, // 1e%d * 2**%d\n", hi.Uint64(), lo.Uint64(), e, be)
- }
- fmt.Fprintf(&out, "}\n")
-
- src, err := format.Source(out.Bytes())
- if err != nil {
- log.Fatal(err)
- }
-
- if err := os.WriteFile("pow10tab.go", src, 0666); err != nil {
- log.Fatal(err)
- }
-}
-
-var top = `// Copyright 2025 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.
-
-// Code generated by: go run pow10gen.go. DO NOT EDIT.
-//
-//go:generate go run pow10gen.go
-
-package strconv
-
-const (
- pow10Min = %d
- pow10Max = %d
-)
-
-
-// pow10Tab holds 128-bit mantissas of powers of 10.
-// The values are scaled so the high bit is always set; there is no "implicit leading 1 bit".
-var pow10Tab = [...]uint128{
-`
diff --git a/src/strconv/pow10tab.go b/src/strconv/pow10tab.go
deleted file mode 100644
index 029ae02b66..0000000000
--- a/src/strconv/pow10tab.go
+++ /dev/null
@@ -1,715 +0,0 @@
-// Copyright 2025 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.
-
-// Code generated by: go run pow10gen.go. DO NOT EDIT.
-//
-//go:generate go run pow10gen.go
-
-package strconv
-
-const (
- pow10Min = -348
- pow10Max = 347
-)
-
-// pow10Tab holds 128-bit mantissas of powers of 10.
-// The values are scaled so the high bit is always set; there is no "implicit leading 1 bit".
-var pow10Tab = [...]uint128{
- {0xfa8fd5a0081c0288, 0x1732c869cd60e453}, // 1e-348 * 2**1284
- {0x9c99e58405118195, 0x0e7fbd42205c8eb4}, // 1e-347 * 2**1280
- {0xc3c05ee50655e1fa, 0x521fac92a873b261}, // 1e-346 * 2**1277
- {0xf4b0769e47eb5a78, 0xe6a797b752909ef9}, // 1e-345 * 2**1274
- {0x98ee4a22ecf3188b, 0x9028bed2939a635c}, // 1e-344 * 2**1270
- {0xbf29dcaba82fdeae, 0x7432ee873880fc33}, // 1e-343 * 2**1267
- {0xeef453d6923bd65a, 0x113faa2906a13b3f}, // 1e-342 * 2**1264
- {0x9558b4661b6565f8, 0x4ac7ca59a424c507}, // 1e-341 * 2**1260
- {0xbaaee17fa23ebf76, 0x5d79bcf00d2df649}, // 1e-340 * 2**1257
- {0xe95a99df8ace6f53, 0xf4d82c2c107973dc}, // 1e-339 * 2**1254
- {0x91d8a02bb6c10594, 0x79071b9b8a4be869}, // 1e-338 * 2**1250
- {0xb64ec836a47146f9, 0x9748e2826cdee284}, // 1e-337 * 2**1247
- {0xe3e27a444d8d98b7, 0xfd1b1b2308169b25}, // 1e-336 * 2**1244
- {0x8e6d8c6ab0787f72, 0xfe30f0f5e50e20f7}, // 1e-335 * 2**1240
- {0xb208ef855c969f4f, 0xbdbd2d335e51a935}, // 1e-334 * 2**1237
- {0xde8b2b66b3bc4723, 0xad2c788035e61382}, // 1e-333 * 2**1234
- {0x8b16fb203055ac76, 0x4c3bcb5021afcc31}, // 1e-332 * 2**1230
- {0xaddcb9e83c6b1793, 0xdf4abe242a1bbf3d}, // 1e-331 * 2**1227
- {0xd953e8624b85dd78, 0xd71d6dad34a2af0d}, // 1e-330 * 2**1224
- {0x87d4713d6f33aa6b, 0x8672648c40e5ad68}, // 1e-329 * 2**1220
- {0xa9c98d8ccb009506, 0x680efdaf511f18c2}, // 1e-328 * 2**1217
- {0xd43bf0effdc0ba48, 0x0212bd1b2566def2}, // 1e-327 * 2**1214
- {0x84a57695fe98746d, 0x014bb630f7604b57}, // 1e-326 * 2**1210
- {0xa5ced43b7e3e9188, 0x419ea3bd35385e2d}, // 1e-325 * 2**1207
- {0xcf42894a5dce35ea, 0x52064cac828675b9}, // 1e-324 * 2**1204
- {0x818995ce7aa0e1b2, 0x7343efebd1940993}, // 1e-323 * 2**1200
- {0xa1ebfb4219491a1f, 0x1014ebe6c5f90bf8}, // 1e-322 * 2**1197
- {0xca66fa129f9b60a6, 0xd41a26e077774ef6}, // 1e-321 * 2**1194
- {0xfd00b897478238d0, 0x8920b098955522b4}, // 1e-320 * 2**1191
- {0x9e20735e8cb16382, 0x55b46e5f5d5535b0}, // 1e-319 * 2**1187
- {0xc5a890362fddbc62, 0xeb2189f734aa831d}, // 1e-318 * 2**1184
- {0xf712b443bbd52b7b, 0xa5e9ec7501d523e4}, // 1e-317 * 2**1181
- {0x9a6bb0aa55653b2d, 0x47b233c92125366e}, // 1e-316 * 2**1177
- {0xc1069cd4eabe89f8, 0x999ec0bb696e840a}, // 1e-315 * 2**1174
- {0xf148440a256e2c76, 0xc00670ea43ca250d}, // 1e-314 * 2**1171
- {0x96cd2a865764dbca, 0x380406926a5e5728}, // 1e-313 * 2**1167
- {0xbc807527ed3e12bc, 0xc605083704f5ecf2}, // 1e-312 * 2**1164
- {0xeba09271e88d976b, 0xf7864a44c633682e}, // 1e-311 * 2**1161
- {0x93445b8731587ea3, 0x7ab3ee6afbe0211d}, // 1e-310 * 2**1157
- {0xb8157268fdae9e4c, 0x5960ea05bad82964}, // 1e-309 * 2**1154
- {0xe61acf033d1a45df, 0x6fb92487298e33bd}, // 1e-308 * 2**1151
- {0x8fd0c16206306bab, 0xa5d3b6d479f8e056}, // 1e-307 * 2**1147
- {0xb3c4f1ba87bc8696, 0x8f48a4899877186c}, // 1e-306 * 2**1144
- {0xe0b62e2929aba83c, 0x331acdabfe94de87}, // 1e-305 * 2**1141
- {0x8c71dcd9ba0b4925, 0x9ff0c08b7f1d0b14}, // 1e-304 * 2**1137
- {0xaf8e5410288e1b6f, 0x07ecf0ae5ee44dd9}, // 1e-303 * 2**1134
- {0xdb71e91432b1a24a, 0xc9e82cd9f69d6150}, // 1e-302 * 2**1131
- {0x892731ac9faf056e, 0xbe311c083a225cd2}, // 1e-301 * 2**1127
- {0xab70fe17c79ac6ca, 0x6dbd630a48aaf406}, // 1e-300 * 2**1124
- {0xd64d3d9db981787d, 0x092cbbccdad5b108}, // 1e-299 * 2**1121
- {0x85f0468293f0eb4e, 0x25bbf56008c58ea5}, // 1e-298 * 2**1117
- {0xa76c582338ed2621, 0xaf2af2b80af6f24e}, // 1e-297 * 2**1114
- {0xd1476e2c07286faa, 0x1af5af660db4aee1}, // 1e-296 * 2**1111
- {0x82cca4db847945ca, 0x50d98d9fc890ed4d}, // 1e-295 * 2**1107
- {0xa37fce126597973c, 0xe50ff107bab528a0}, // 1e-294 * 2**1104
- {0xcc5fc196fefd7d0c, 0x1e53ed49a96272c8}, // 1e-293 * 2**1101
- {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7a}, // 1e-292 * 2**1098
- {0x9faacf3df73609b1, 0x77b191618c54e9ac}, // 1e-291 * 2**1094
- {0xc795830d75038c1d, 0xd59df5b9ef6a2417}, // 1e-290 * 2**1091
- {0xf97ae3d0d2446f25, 0x4b0573286b44ad1d}, // 1e-289 * 2**1088
- {0x9becce62836ac577, 0x4ee367f9430aec32}, // 1e-288 * 2**1084
- {0xc2e801fb244576d5, 0x229c41f793cda73f}, // 1e-287 * 2**1081
- {0xf3a20279ed56d48a, 0x6b43527578c1110f}, // 1e-286 * 2**1078
- {0x9845418c345644d6, 0x830a13896b78aaa9}, // 1e-285 * 2**1074
- {0xbe5691ef416bd60c, 0x23cc986bc656d553}, // 1e-284 * 2**1071
- {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa8}, // 1e-283 * 2**1068
- {0x94b3a202eb1c3f39, 0x7bf7d71432f3d6a9}, // 1e-282 * 2**1064
- {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc53}, // 1e-281 * 2**1061
- {0xe858ad248f5c22c9, 0xd1b3400f8f9cff68}, // 1e-280 * 2**1058
- {0x91376c36d99995be, 0x23100809b9c21fa1}, // 1e-279 * 2**1054
- {0xb58547448ffffb2d, 0xabd40a0c2832a78a}, // 1e-278 * 2**1051
- {0xe2e69915b3fff9f9, 0x16c90c8f323f516c}, // 1e-277 * 2**1048
- {0x8dd01fad907ffc3b, 0xae3da7d97f6792e3}, // 1e-276 * 2**1044
- {0xb1442798f49ffb4a, 0x99cd11cfdf41779c}, // 1e-275 * 2**1041
- {0xdd95317f31c7fa1d, 0x40405643d711d583}, // 1e-274 * 2**1038
- {0x8a7d3eef7f1cfc52, 0x482835ea666b2572}, // 1e-273 * 2**1034
- {0xad1c8eab5ee43b66, 0xda3243650005eecf}, // 1e-272 * 2**1031
- {0xd863b256369d4a40, 0x90bed43e40076a82}, // 1e-271 * 2**1028
- {0x873e4f75e2224e68, 0x5a7744a6e804a291}, // 1e-270 * 2**1024
- {0xa90de3535aaae202, 0x711515d0a205cb36}, // 1e-269 * 2**1021
- {0xd3515c2831559a83, 0x0d5a5b44ca873e03}, // 1e-268 * 2**1018
- {0x8412d9991ed58091, 0xe858790afe9486c2}, // 1e-267 * 2**1014
- {0xa5178fff668ae0b6, 0x626e974dbe39a872}, // 1e-266 * 2**1011
- {0xce5d73ff402d98e3, 0xfb0a3d212dc8128f}, // 1e-265 * 2**1008
- {0x80fa687f881c7f8e, 0x7ce66634bc9d0b99}, // 1e-264 * 2**1004
- {0xa139029f6a239f72, 0x1c1fffc1ebc44e80}, // 1e-263 * 2**1001
- {0xc987434744ac874e, 0xa327ffb266b56220}, // 1e-262 * 2**998
- {0xfbe9141915d7a922, 0x4bf1ff9f0062baa8}, // 1e-261 * 2**995
- {0x9d71ac8fada6c9b5, 0x6f773fc3603db4a9}, // 1e-260 * 2**991
- {0xc4ce17b399107c22, 0xcb550fb4384d21d3}, // 1e-259 * 2**988
- {0xf6019da07f549b2b, 0x7e2a53a146606a48}, // 1e-258 * 2**985
- {0x99c102844f94e0fb, 0x2eda7444cbfc426d}, // 1e-257 * 2**981
- {0xc0314325637a1939, 0xfa911155fefb5308}, // 1e-256 * 2**978
- {0xf03d93eebc589f88, 0x793555ab7eba27ca}, // 1e-255 * 2**975
- {0x96267c7535b763b5, 0x4bc1558b2f3458de}, // 1e-254 * 2**971
- {0xbbb01b9283253ca2, 0x9eb1aaedfb016f16}, // 1e-253 * 2**968
- {0xea9c227723ee8bcb, 0x465e15a979c1cadc}, // 1e-252 * 2**965
- {0x92a1958a7675175f, 0x0bfacd89ec191ec9}, // 1e-251 * 2**961
- {0xb749faed14125d36, 0xcef980ec671f667b}, // 1e-250 * 2**958
- {0xe51c79a85916f484, 0x82b7e12780e7401a}, // 1e-249 * 2**955
- {0x8f31cc0937ae58d2, 0xd1b2ecb8b0908810}, // 1e-248 * 2**951
- {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa15}, // 1e-247 * 2**948
- {0xdfbdcece67006ac9, 0x67a791e093e1d49a}, // 1e-246 * 2**945
- {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e0}, // 1e-245 * 2**941
- {0xaecc49914078536d, 0x58fae9f773886e18}, // 1e-244 * 2**938
- {0xda7f5bf590966848, 0xaf39a475506a899e}, // 1e-243 * 2**935
- {0x888f99797a5e012d, 0x6d8406c952429603}, // 1e-242 * 2**931
- {0xaab37fd7d8f58178, 0xc8e5087ba6d33b83}, // 1e-241 * 2**928
- {0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a64}, // 1e-240 * 2**925
- {0x855c3be0a17fcd26, 0x5cf2eea09a55067f}, // 1e-239 * 2**921
- {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481e}, // 1e-238 * 2**918
- {0xd0601d8efc57b08b, 0xf13b94daf124da26}, // 1e-237 * 2**915
- {0x823c12795db6ce57, 0x76c53d08d6b70858}, // 1e-236 * 2**911
- {0xa2cb1717b52481ed, 0x54768c4b0c64ca6e}, // 1e-235 * 2**908
- {0xcb7ddcdda26da268, 0xa9942f5dcf7dfd09}, // 1e-234 * 2**905
- {0xfe5d54150b090b02, 0xd3f93b35435d7c4c}, // 1e-233 * 2**902
- {0x9efa548d26e5a6e1, 0xc47bc5014a1a6daf}, // 1e-232 * 2**898
- {0xc6b8e9b0709f109a, 0x359ab6419ca1091b}, // 1e-231 * 2**895
- {0xf867241c8cc6d4c0, 0xc30163d203c94b62}, // 1e-230 * 2**892
- {0x9b407691d7fc44f8, 0x79e0de63425dcf1d}, // 1e-229 * 2**888
- {0xc21094364dfb5636, 0x985915fc12f542e4}, // 1e-228 * 2**885
- {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939d}, // 1e-227 * 2**882
- {0x979cf3ca6cec5b5a, 0xa705992ceecf9c42}, // 1e-226 * 2**878
- {0xbd8430bd08277231, 0x50c6ff782a838353}, // 1e-225 * 2**875
- {0xece53cec4a314ebd, 0xa4f8bf5635246428}, // 1e-224 * 2**872
- {0x940f4613ae5ed136, 0x871b7795e136be99}, // 1e-223 * 2**868
- {0xb913179899f68584, 0x28e2557b59846e3f}, // 1e-222 * 2**865
- {0xe757dd7ec07426e5, 0x331aeada2fe589cf}, // 1e-221 * 2**862
- {0x9096ea6f3848984f, 0x3ff0d2c85def7621}, // 1e-220 * 2**858
- {0xb4bca50b065abe63, 0x0fed077a756b53a9}, // 1e-219 * 2**855
- {0xe1ebce4dc7f16dfb, 0xd3e8495912c62894}, // 1e-218 * 2**852
- {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95c}, // 1e-217 * 2**848
- {0xb080392cc4349dec, 0xbd8d794d96aacfb3}, // 1e-216 * 2**845
- {0xdca04777f541c567, 0xecf0d7a0fc5583a0}, // 1e-215 * 2**842
- {0x89e42caaf9491b60, 0xf41686c49db57244}, // 1e-214 * 2**838
- {0xac5d37d5b79b6239, 0x311c2875c522ced5}, // 1e-213 * 2**835
- {0xd77485cb25823ac7, 0x7d633293366b828b}, // 1e-212 * 2**832
- {0x86a8d39ef77164bc, 0xae5dff9c02033197}, // 1e-211 * 2**828
- {0xa8530886b54dbdeb, 0xd9f57f830283fdfc}, // 1e-210 * 2**825
- {0xd267caa862a12d66, 0xd072df63c324fd7b}, // 1e-209 * 2**822
- {0x8380dea93da4bc60, 0x4247cb9e59f71e6d}, // 1e-208 * 2**818
- {0xa46116538d0deb78, 0x52d9be85f074e608}, // 1e-207 * 2**815
- {0xcd795be870516656, 0x67902e276c921f8b}, // 1e-206 * 2**812
- {0x806bd9714632dff6, 0x00ba1cd8a3db53b6}, // 1e-205 * 2**808
- {0xa086cfcd97bf97f3, 0x80e8a40eccd228a4}, // 1e-204 * 2**805
- {0xc8a883c0fdaf7df0, 0x6122cd128006b2cd}, // 1e-203 * 2**802
- {0xfad2a4b13d1b5d6c, 0x796b805720085f81}, // 1e-202 * 2**799
- {0x9cc3a6eec6311a63, 0xcbe3303674053bb0}, // 1e-201 * 2**795
- {0xc3f490aa77bd60fc, 0xbedbfc4411068a9c}, // 1e-200 * 2**792
- {0xf4f1b4d515acb93b, 0xee92fb5515482d44}, // 1e-199 * 2**789
- {0x991711052d8bf3c5, 0x751bdd152d4d1c4a}, // 1e-198 * 2**785
- {0xbf5cd54678eef0b6, 0xd262d45a78a0635d}, // 1e-197 * 2**782
- {0xef340a98172aace4, 0x86fb897116c87c34}, // 1e-196 * 2**779
- {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da0}, // 1e-195 * 2**775
- {0xbae0a846d2195712, 0x8974836059cca109}, // 1e-194 * 2**772
- {0xe998d258869facd7, 0x2bd1a438703fc94b}, // 1e-193 * 2**769
- {0x91ff83775423cc06, 0x7b6306a34627ddcf}, // 1e-192 * 2**765
- {0xb67f6455292cbf08, 0x1a3bc84c17b1d542}, // 1e-191 * 2**762
- {0xe41f3d6a7377eeca, 0x20caba5f1d9e4a93}, // 1e-190 * 2**759
- {0x8e938662882af53e, 0x547eb47b7282ee9c}, // 1e-189 * 2**755
- {0xb23867fb2a35b28d, 0xe99e619a4f23aa43}, // 1e-188 * 2**752
- {0xdec681f9f4c31f31, 0x6405fa00e2ec94d4}, // 1e-187 * 2**749
- {0x8b3c113c38f9f37e, 0xde83bc408dd3dd04}, // 1e-186 * 2**745
- {0xae0b158b4738705e, 0x9624ab50b148d445}, // 1e-185 * 2**742
- {0xd98ddaee19068c76, 0x3badd624dd9b0957}, // 1e-184 * 2**739
- {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d6}, // 1e-183 * 2**735
- {0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4c}, // 1e-182 * 2**732
- {0xd47487cc8470652b, 0x7647c3200069671f}, // 1e-181 * 2**729
- {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e073}, // 1e-180 * 2**725
- {0xa5fb0a17c777cf09, 0xf468107100525890}, // 1e-179 * 2**722
- {0xcf79cc9db955c2cc, 0x7182148d4066eeb4}, // 1e-178 * 2**719
- {0x81ac1fe293d599bf, 0xc6f14cd848405530}, // 1e-177 * 2**715
- {0xa21727db38cb002f, 0xb8ada00e5a506a7c}, // 1e-176 * 2**712
- {0xca9cf1d206fdc03b, 0xa6d90811f0e4851c}, // 1e-175 * 2**709
- {0xfd442e4688bd304a, 0x908f4a166d1da663}, // 1e-174 * 2**706
- {0x9e4a9cec15763e2e, 0x9a598e4e043287fe}, // 1e-173 * 2**702
- {0xc5dd44271ad3cdba, 0x40eff1e1853f29fd}, // 1e-172 * 2**699
- {0xf7549530e188c128, 0xd12bee59e68ef47c}, // 1e-171 * 2**696
- {0x9a94dd3e8cf578b9, 0x82bb74f8301958ce}, // 1e-170 * 2**692
- {0xc13a148e3032d6e7, 0xe36a52363c1faf01}, // 1e-169 * 2**689
- {0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac1}, // 1e-168 * 2**686
- {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0b9}, // 1e-167 * 2**682
- {0xbcb2b812db11a5de, 0x7415d448f6b6f0e7}, // 1e-166 * 2**679
- {0xebdf661791d60f56, 0x111b495b3464ad21}, // 1e-165 * 2**676
- {0x936b9fcebb25c995, 0xcab10dd900beec34}, // 1e-164 * 2**672
- {0xb84687c269ef3bfb, 0x3d5d514f40eea742}, // 1e-163 * 2**669
- {0xe65829b3046b0afa, 0x0cb4a5a3112a5112}, // 1e-162 * 2**666
- {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ab}, // 1e-161 * 2**662
- {0xb3f4e093db73a093, 0x59ed216765690f56}, // 1e-160 * 2**659
- {0xe0f218b8d25088b8, 0x306869c13ec3532c}, // 1e-159 * 2**656
- {0x8c974f7383725573, 0x1e414218c73a13fb}, // 1e-158 * 2**652
- {0xafbd2350644eeacf, 0xe5d1929ef90898fa}, // 1e-157 * 2**649
- {0xdbac6c247d62a583, 0xdf45f746b74abf39}, // 1e-156 * 2**646
- {0x894bc396ce5da772, 0x6b8bba8c328eb783}, // 1e-155 * 2**642
- {0xab9eb47c81f5114f, 0x066ea92f3f326564}, // 1e-154 * 2**639
- {0xd686619ba27255a2, 0xc80a537b0efefebd}, // 1e-153 * 2**636
- {0x8613fd0145877585, 0xbd06742ce95f5f36}, // 1e-152 * 2**632
- {0xa798fc4196e952e7, 0x2c48113823b73704}, // 1e-151 * 2**629
- {0xd17f3b51fca3a7a0, 0xf75a15862ca504c5}, // 1e-150 * 2**626
- {0x82ef85133de648c4, 0x9a984d73dbe722fb}, // 1e-149 * 2**622
- {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebba}, // 1e-148 * 2**619
- {0xcc963fee10b7d1b3, 0x318df905079926a8}, // 1e-147 * 2**616
- {0xffbbcfe994e5c61f, 0xfdf17746497f7052}, // 1e-146 * 2**613
- {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa633}, // 1e-145 * 2**609
- {0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc0}, // 1e-144 * 2**606
- {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b0}, // 1e-143 * 2**603
- {0x9c1661a651213e2d, 0x06bea10ca65c084e}, // 1e-142 * 2**599
- {0xc31bfa0fe5698db8, 0x486e494fcff30a62}, // 1e-141 * 2**596
- {0xf3e2f893dec3f126, 0x5a89dba3c3efccfa}, // 1e-140 * 2**593
- {0x986ddb5c6b3a76b7, 0xf89629465a75e01c}, // 1e-139 * 2**589
- {0xbe89523386091465, 0xf6bbb397f1135823}, // 1e-138 * 2**586
- {0xee2ba6c0678b597f, 0x746aa07ded582e2c}, // 1e-137 * 2**583
- {0x94db483840b717ef, 0xa8c2a44eb4571cdc}, // 1e-136 * 2**579
- {0xba121a4650e4ddeb, 0x92f34d62616ce413}, // 1e-135 * 2**576
- {0xe896a0d7e51e1566, 0x77b020baf9c81d17}, // 1e-134 * 2**573
- {0x915e2486ef32cd60, 0x0ace1474dc1d122e}, // 1e-133 * 2**569
- {0xb5b5ada8aaff80b8, 0x0d819992132456ba}, // 1e-132 * 2**566
- {0xe3231912d5bf60e6, 0x10e1fff697ed6c69}, // 1e-131 * 2**563
- {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c1}, // 1e-130 * 2**559
- {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb2}, // 1e-129 * 2**556
- {0xddd0467c64bce4a0, 0xac7cb3f6d05ddbde}, // 1e-128 * 2**553
- {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96b}, // 1e-127 * 2**549
- {0xad4ab7112eb3929d, 0x86c16c98d2c953c6}, // 1e-126 * 2**546
- {0xd89d64d57a607744, 0xe871c7bf077ba8b7}, // 1e-125 * 2**543
- {0x87625f056c7c4a8b, 0x11471cd764ad4972}, // 1e-124 * 2**539
- {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bcf}, // 1e-123 * 2**536
- {0xd389b47879823479, 0x4aff1d108d4ec2c3}, // 1e-122 * 2**533
- {0x843610cb4bf160cb, 0xcedf722a585139ba}, // 1e-121 * 2**529
- {0xa54394fe1eedb8fe, 0xc2974eb4ee658828}, // 1e-120 * 2**526
- {0xce947a3da6a9273e, 0x733d226229feea32}, // 1e-119 * 2**523
- {0x811ccc668829b887, 0x0806357d5a3f525f}, // 1e-118 * 2**519
- {0xa163ff802a3426a8, 0xca07c2dcb0cf26f7}, // 1e-117 * 2**516
- {0xc9bcff6034c13052, 0xfc89b393dd02f0b5}, // 1e-116 * 2**513
- {0xfc2c3f3841f17c67, 0xbbac2078d443ace2}, // 1e-115 * 2**510
- {0x9d9ba7832936edc0, 0xd54b944b84aa4c0d}, // 1e-114 * 2**506
- {0xc5029163f384a931, 0x0a9e795e65d4df11}, // 1e-113 * 2**503
- {0xf64335bcf065d37d, 0x4d4617b5ff4a16d5}, // 1e-112 * 2**500
- {0x99ea0196163fa42e, 0x504bced1bf8e4e45}, // 1e-111 * 2**496
- {0xc06481fb9bcf8d39, 0xe45ec2862f71e1d6}, // 1e-110 * 2**493
- {0xf07da27a82c37088, 0x5d767327bb4e5a4c}, // 1e-109 * 2**490
- {0x964e858c91ba2655, 0x3a6a07f8d510f86f}, // 1e-108 * 2**486
- {0xbbe226efb628afea, 0x890489f70a55368b}, // 1e-107 * 2**483
- {0xeadab0aba3b2dbe5, 0x2b45ac74ccea842e}, // 1e-106 * 2**480
- {0x92c8ae6b464fc96f, 0x3b0b8bc90012929d}, // 1e-105 * 2**476
- {0xb77ada0617e3bbcb, 0x09ce6ebb40173744}, // 1e-104 * 2**473
- {0xe55990879ddcaabd, 0xcc420a6a101d0515}, // 1e-103 * 2**470
- {0x8f57fa54c2a9eab6, 0x9fa946824a12232d}, // 1e-102 * 2**466
- {0xb32df8e9f3546564, 0x47939822dc96abf9}, // 1e-101 * 2**463
- {0xdff9772470297ebd, 0x59787e2b93bc56f7}, // 1e-100 * 2**460
- {0x8bfbea76c619ef36, 0x57eb4edb3c55b65a}, // 1e-99 * 2**456
- {0xaefae51477a06b03, 0xede622920b6b23f1}, // 1e-98 * 2**453
- {0xdab99e59958885c4, 0xe95fab368e45eced}, // 1e-97 * 2**450
- {0x88b402f7fd75539b, 0x11dbcb0218ebb414}, // 1e-96 * 2**446
- {0xaae103b5fcd2a881, 0xd652bdc29f26a119}, // 1e-95 * 2**443
- {0xd59944a37c0752a2, 0x4be76d3346f0495f}, // 1e-94 * 2**440
- {0x857fcae62d8493a5, 0x6f70a4400c562ddb}, // 1e-93 * 2**436
- {0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb952}, // 1e-92 * 2**433
- {0xd097ad07a71f26b2, 0x7e2000a41346a7a7}, // 1e-91 * 2**430
- {0x825ecc24c873782f, 0x8ed400668c0c28c8}, // 1e-90 * 2**426
- {0xa2f67f2dfa90563b, 0x728900802f0f32fa}, // 1e-89 * 2**423
- {0xcbb41ef979346bca, 0x4f2b40a03ad2ffb9}, // 1e-88 * 2**420
- {0xfea126b7d78186bc, 0xe2f610c84987bfa8}, // 1e-87 * 2**417
- {0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7c9}, // 1e-86 * 2**413
- {0xc6ede63fa05d3143, 0x91503d1c79720dbb}, // 1e-85 * 2**410
- {0xf8a95fcf88747d94, 0x75a44c6397ce912a}, // 1e-84 * 2**407
- {0x9b69dbe1b548ce7c, 0xc986afbe3ee11aba}, // 1e-83 * 2**403
- {0xc24452da229b021b, 0xfbe85badce996168}, // 1e-82 * 2**400
- {0xf2d56790ab41c2a2, 0xfae27299423fb9c3}, // 1e-81 * 2**397
- {0x97c560ba6b0919a5, 0xdccd879fc967d41a}, // 1e-80 * 2**393
- {0xbdb6b8e905cb600f, 0x5400e987bbc1c920}, // 1e-79 * 2**390
- {0xed246723473e3813, 0x290123e9aab23b68}, // 1e-78 * 2**387
- {0x9436c0760c86e30b, 0xf9a0b6720aaf6521}, // 1e-77 * 2**383
- {0xb94470938fa89bce, 0xf808e40e8d5b3e69}, // 1e-76 * 2**380
- {0xe7958cb87392c2c2, 0xb60b1d1230b20e04}, // 1e-75 * 2**377
- {0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c2}, // 1e-74 * 2**373
- {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af3}, // 1e-73 * 2**370
- {0xe2280b6c20dd5232, 0x25c6da63c38de1b0}, // 1e-72 * 2**367
- {0x8d590723948a535f, 0x579c487e5a38ad0e}, // 1e-71 * 2**363
- {0xb0af48ec79ace837, 0x2d835a9df0c6d851}, // 1e-70 * 2**360
- {0xdcdb1b2798182244, 0xf8e431456cf88e65}, // 1e-69 * 2**357
- {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b58ff}, // 1e-68 * 2**353
- {0xac8b2d36eed2dac5, 0xe272467e3d222f3f}, // 1e-67 * 2**350
- {0xd7adf884aa879177, 0x5b0ed81dcc6abb0f}, // 1e-66 * 2**347
- {0x86ccbb52ea94baea, 0x98e947129fc2b4e9}, // 1e-65 * 2**343
- {0xa87fea27a539e9a5, 0x3f2398d747b36224}, // 1e-64 * 2**340
- {0xd29fe4b18e88640e, 0x8eec7f0d19a03aad}, // 1e-63 * 2**337
- {0x83a3eeeef9153e89, 0x1953cf68300424ac}, // 1e-62 * 2**333
- {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd7}, // 1e-61 * 2**330
- {0xcdb02555653131b6, 0x3792f412cb06794d}, // 1e-60 * 2**327
- {0x808e17555f3ebf11, 0xe2bbd88bbee40bd0}, // 1e-59 * 2**323
- {0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec4}, // 1e-58 * 2**320
- {0xc8de047564d20a8b, 0xf245825a5a445275}, // 1e-57 * 2**317
- {0xfb158592be068d2e, 0xeed6e2f0f0d56712}, // 1e-56 * 2**314
- {0x9ced737bb6c4183d, 0x55464dd69685606b}, // 1e-55 * 2**310
- {0xc428d05aa4751e4c, 0xaa97e14c3c26b886}, // 1e-54 * 2**307
- {0xf53304714d9265df, 0xd53dd99f4b3066a8}, // 1e-53 * 2**304
- {0x993fe2c6d07b7fab, 0xe546a8038efe4029}, // 1e-52 * 2**300
- {0xbf8fdb78849a5f96, 0xde98520472bdd033}, // 1e-51 * 2**297
- {0xef73d256a5c0f77c, 0x963e66858f6d4440}, // 1e-50 * 2**294
- {0x95a8637627989aad, 0xdde7001379a44aa8}, // 1e-49 * 2**290
- {0xbb127c53b17ec159, 0x5560c018580d5d52}, // 1e-48 * 2**287
- {0xe9d71b689dde71af, 0xaab8f01e6e10b4a6}, // 1e-47 * 2**284
- {0x9226712162ab070d, 0xcab3961304ca70e8}, // 1e-46 * 2**280
- {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d22}, // 1e-45 * 2**277
- {0xe45c10c42a2b3b05, 0x8cb89a7db77c506a}, // 1e-44 * 2**274
- {0x8eb98a7a9a5b04e3, 0x77f3608e92adb242}, // 1e-43 * 2**270
- {0xb267ed1940f1c61c, 0x55f038b237591ed3}, // 1e-42 * 2**267
- {0xdf01e85f912e37a3, 0x6b6c46dec52f6688}, // 1e-41 * 2**264
- {0x8b61313bbabce2c6, 0x2323ac4b3b3da015}, // 1e-40 * 2**260
- {0xae397d8aa96c1b77, 0xabec975e0a0d081a}, // 1e-39 * 2**257
- {0xd9c7dced53c72255, 0x96e7bd358c904a21}, // 1e-38 * 2**254
- {0x881cea14545c7575, 0x7e50d64177da2e54}, // 1e-37 * 2**250
- {0xaa242499697392d2, 0xdde50bd1d5d0b9e9}, // 1e-36 * 2**247
- {0xd4ad2dbfc3d07787, 0x955e4ec64b44e864}, // 1e-35 * 2**244
- {0x84ec3c97da624ab4, 0xbd5af13bef0b113e}, // 1e-34 * 2**240
- {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58e}, // 1e-33 * 2**237
- {0xcfb11ead453994ba, 0x67de18eda5814af2}, // 1e-32 * 2**234
- {0x81ceb32c4b43fcf4, 0x80eacf948770ced7}, // 1e-31 * 2**230
- {0xa2425ff75e14fc31, 0xa1258379a94d028d}, // 1e-30 * 2**227
- {0xcad2f7f5359a3b3e, 0x096ee45813a04330}, // 1e-29 * 2**224
- {0xfd87b5f28300ca0d, 0x8bca9d6e188853fc}, // 1e-28 * 2**221
- {0x9e74d1b791e07e48, 0x775ea264cf55347d}, // 1e-27 * 2**217
- {0xc612062576589dda, 0x95364afe032a819d}, // 1e-26 * 2**214
- {0xf79687aed3eec551, 0x3a83ddbd83f52204}, // 1e-25 * 2**211
- {0x9abe14cd44753b52, 0xc4926a9672793542}, // 1e-24 * 2**207
- {0xc16d9a0095928a27, 0x75b7053c0f178293}, // 1e-23 * 2**204
- {0xf1c90080baf72cb1, 0x5324c68b12dd6338}, // 1e-22 * 2**201
- {0x971da05074da7bee, 0xd3f6fc16ebca5e03}, // 1e-21 * 2**197
- {0xbce5086492111aea, 0x88f4bb1ca6bcf584}, // 1e-20 * 2**194
- {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e5}, // 1e-19 * 2**191
- {0x9392ee8e921d5d07, 0x3aff322e62439fcf}, // 1e-18 * 2**187
- {0xb877aa3236a4b449, 0x09befeb9fad487c2}, // 1e-17 * 2**184
- {0xe69594bec44de15b, 0x4c2ebe687989a9b3}, // 1e-16 * 2**181
- {0x901d7cf73ab0acd9, 0x0f9d37014bf60a10}, // 1e-15 * 2**177
- {0xb424dc35095cd80f, 0x538484c19ef38c94}, // 1e-14 * 2**174
- {0xe12e13424bb40e13, 0x2865a5f206b06fb9}, // 1e-13 * 2**171
- {0x8cbccc096f5088cb, 0xf93f87b7442e45d3}, // 1e-12 * 2**167
- {0xafebff0bcb24aafe, 0xf78f69a51539d748}, // 1e-11 * 2**164
- {0xdbe6fecebdedd5be, 0xb573440e5a884d1b}, // 1e-10 * 2**161
- {0x89705f4136b4a597, 0x31680a88f8953030}, // 1e-9 * 2**157
- {0xabcc77118461cefc, 0xfdc20d2b36ba7c3d}, // 1e-8 * 2**154
- {0xd6bf94d5e57a42bc, 0x3d32907604691b4c}, // 1e-7 * 2**151
- {0x8637bd05af6c69b5, 0xa63f9a49c2c1b10f}, // 1e-6 * 2**147
- {0xa7c5ac471b478423, 0x0fcf80dc33721d53}, // 1e-5 * 2**144
- {0xd1b71758e219652b, 0xd3c36113404ea4a8}, // 1e-4 * 2**141
- {0x83126e978d4fdf3b, 0x645a1cac083126e9}, // 1e-3 * 2**137
- {0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a3}, // 1e-2 * 2**134
- {0xcccccccccccccccc, 0xcccccccccccccccc}, // 1e-1 * 2**131
- {0x8000000000000000, 0x0000000000000000}, // 1e0 * 2**127
- {0xa000000000000000, 0x0000000000000000}, // 1e1 * 2**124
- {0xc800000000000000, 0x0000000000000000}, // 1e2 * 2**121
- {0xfa00000000000000, 0x0000000000000000}, // 1e3 * 2**118
- {0x9c40000000000000, 0x0000000000000000}, // 1e4 * 2**114
- {0xc350000000000000, 0x0000000000000000}, // 1e5 * 2**111
- {0xf424000000000000, 0x0000000000000000}, // 1e6 * 2**108
- {0x9896800000000000, 0x0000000000000000}, // 1e7 * 2**104
- {0xbebc200000000000, 0x0000000000000000}, // 1e8 * 2**101
- {0xee6b280000000000, 0x0000000000000000}, // 1e9 * 2**98
- {0x9502f90000000000, 0x0000000000000000}, // 1e10 * 2**94
- {0xba43b74000000000, 0x0000000000000000}, // 1e11 * 2**91
- {0xe8d4a51000000000, 0x0000000000000000}, // 1e12 * 2**88
- {0x9184e72a00000000, 0x0000000000000000}, // 1e13 * 2**84
- {0xb5e620f480000000, 0x0000000000000000}, // 1e14 * 2**81
- {0xe35fa931a0000000, 0x0000000000000000}, // 1e15 * 2**78
- {0x8e1bc9bf04000000, 0x0000000000000000}, // 1e16 * 2**74
- {0xb1a2bc2ec5000000, 0x0000000000000000}, // 1e17 * 2**71
- {0xde0b6b3a76400000, 0x0000000000000000}, // 1e18 * 2**68
- {0x8ac7230489e80000, 0x0000000000000000}, // 1e19 * 2**64
- {0xad78ebc5ac620000, 0x0000000000000000}, // 1e20 * 2**61
- {0xd8d726b7177a8000, 0x0000000000000000}, // 1e21 * 2**58
- {0x878678326eac9000, 0x0000000000000000}, // 1e22 * 2**54
- {0xa968163f0a57b400, 0x0000000000000000}, // 1e23 * 2**51
- {0xd3c21bcecceda100, 0x0000000000000000}, // 1e24 * 2**48
- {0x84595161401484a0, 0x0000000000000000}, // 1e25 * 2**44
- {0xa56fa5b99019a5c8, 0x0000000000000000}, // 1e26 * 2**41
- {0xcecb8f27f4200f3a, 0x0000000000000000}, // 1e27 * 2**38
- {0x813f3978f8940984, 0x4000000000000000}, // 1e28 * 2**34
- {0xa18f07d736b90be5, 0x5000000000000000}, // 1e29 * 2**31
- {0xc9f2c9cd04674ede, 0xa400000000000000}, // 1e30 * 2**28
- {0xfc6f7c4045812296, 0x4d00000000000000}, // 1e31 * 2**25
- {0x9dc5ada82b70b59d, 0xf020000000000000}, // 1e32 * 2**21
- {0xc5371912364ce305, 0x6c28000000000000}, // 1e33 * 2**18
- {0xf684df56c3e01bc6, 0xc732000000000000}, // 1e34 * 2**15
- {0x9a130b963a6c115c, 0x3c7f400000000000}, // 1e35 * 2**11
- {0xc097ce7bc90715b3, 0x4b9f100000000000}, // 1e36 * 2**8
- {0xf0bdc21abb48db20, 0x1e86d40000000000}, // 1e37 * 2**5
- {0x96769950b50d88f4, 0x1314448000000000}, // 1e38 * 2**1
- {0xbc143fa4e250eb31, 0x17d955a000000000}, // 1e39 * 2**-2
- {0xeb194f8e1ae525fd, 0x5dcfab0800000000}, // 1e40 * 2**-5
- {0x92efd1b8d0cf37be, 0x5aa1cae500000000}, // 1e41 * 2**-9
- {0xb7abc627050305ad, 0xf14a3d9e40000000}, // 1e42 * 2**-12
- {0xe596b7b0c643c719, 0x6d9ccd05d0000000}, // 1e43 * 2**-15
- {0x8f7e32ce7bea5c6f, 0xe4820023a2000000}, // 1e44 * 2**-19
- {0xb35dbf821ae4f38b, 0xdda2802c8a800000}, // 1e45 * 2**-22
- {0xe0352f62a19e306e, 0xd50b2037ad200000}, // 1e46 * 2**-25
- {0x8c213d9da502de45, 0x4526f422cc340000}, // 1e47 * 2**-29
- {0xaf298d050e4395d6, 0x9670b12b7f410000}, // 1e48 * 2**-32
- {0xdaf3f04651d47b4c, 0x3c0cdd765f114000}, // 1e49 * 2**-35
- {0x88d8762bf324cd0f, 0xa5880a69fb6ac800}, // 1e50 * 2**-39
- {0xab0e93b6efee0053, 0x8eea0d047a457a00}, // 1e51 * 2**-42
- {0xd5d238a4abe98068, 0x72a4904598d6d880}, // 1e52 * 2**-45
- {0x85a36366eb71f041, 0x47a6da2b7f864750}, // 1e53 * 2**-49
- {0xa70c3c40a64e6c51, 0x999090b65f67d924}, // 1e54 * 2**-52
- {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d}, // 1e55 * 2**-55
- {0x82818f1281ed449f, 0xbff8f10e7a8921a4}, // 1e56 * 2**-59
- {0xa321f2d7226895c7, 0xaff72d52192b6a0d}, // 1e57 * 2**-62
- {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490}, // 1e58 * 2**-65
- {0xfee50b7025c36a08, 0x02f236d04753d5b4}, // 1e59 * 2**-68
- {0x9f4f2726179a2245, 0x01d762422c946590}, // 1e60 * 2**-72
- {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5}, // 1e61 * 2**-75
- {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2}, // 1e62 * 2**-78
- {0x9b934c3b330c8577, 0x63cc55f49f88eb2f}, // 1e63 * 2**-82
- {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb}, // 1e64 * 2**-85
- {0xf316271c7fc3908a, 0x8bef464e3945ef7a}, // 1e65 * 2**-88
- {0x97edd871cfda3a56, 0x97758bf0e3cbb5ac}, // 1e66 * 2**-92
- {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317}, // 1e67 * 2**-95
- {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd}, // 1e68 * 2**-98
- {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a}, // 1e69 * 2**-102
- {0xb975d6b6ee39e436, 0xb3e2fd538e122b44}, // 1e70 * 2**-105
- {0xe7d34c64a9c85d44, 0x60dbbca87196b616}, // 1e71 * 2**-108
- {0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd}, // 1e72 * 2**-112
- {0xb51d13aea4a488dd, 0x6babab6398bdbe41}, // 1e73 * 2**-115
- {0xe264589a4dcdab14, 0xc696963c7eed2dd1}, // 1e74 * 2**-118
- {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2}, // 1e75 * 2**-122
- {0xb0de65388cc8ada8, 0x3b25a55f43294bcb}, // 1e76 * 2**-125
- {0xdd15fe86affad912, 0x49ef0eb713f39ebe}, // 1e77 * 2**-128
- {0x8a2dbf142dfcc7ab, 0x6e3569326c784337}, // 1e78 * 2**-132
- {0xacb92ed9397bf996, 0x49c2c37f07965404}, // 1e79 * 2**-135
- {0xd7e77a8f87daf7fb, 0xdc33745ec97be906}, // 1e80 * 2**-138
- {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3}, // 1e81 * 2**-142
- {0xa8acd7c0222311bc, 0xc40832ea0d68ce0c}, // 1e82 * 2**-145
- {0xd2d80db02aabd62b, 0xf50a3fa490c30190}, // 1e83 * 2**-148
- {0x83c7088e1aab65db, 0x792667c6da79e0fa}, // 1e84 * 2**-152
- {0xa4b8cab1a1563f52, 0x577001b891185938}, // 1e85 * 2**-155
- {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86}, // 1e86 * 2**-158
- {0x80b05e5ac60b6178, 0x544f8158315b05b4}, // 1e87 * 2**-162
- {0xa0dc75f1778e39d6, 0x696361ae3db1c721}, // 1e88 * 2**-165
- {0xc913936dd571c84c, 0x03bc3a19cd1e38e9}, // 1e89 * 2**-168
- {0xfb5878494ace3a5f, 0x04ab48a04065c723}, // 1e90 * 2**-171
- {0x9d174b2dcec0e47b, 0x62eb0d64283f9c76}, // 1e91 * 2**-175
- {0xc45d1df942711d9a, 0x3ba5d0bd324f8394}, // 1e92 * 2**-178
- {0xf5746577930d6500, 0xca8f44ec7ee36479}, // 1e93 * 2**-181
- {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb}, // 1e94 * 2**-185
- {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e}, // 1e95 * 2**-188
- {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e}, // 1e96 * 2**-191
- {0x95d04aee3b80ece5, 0xbba1f1d158724a12}, // 1e97 * 2**-195
- {0xbb445da9ca61281f, 0x2a8a6e45ae8edc97}, // 1e98 * 2**-198
- {0xea1575143cf97226, 0xf52d09d71a3293bd}, // 1e99 * 2**-201
- {0x924d692ca61be758, 0x593c2626705f9c56}, // 1e100 * 2**-205
- {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c}, // 1e101 * 2**-208
- {0xe498f455c38b997a, 0x0b6dfb9c0f956447}, // 1e102 * 2**-211
- {0x8edf98b59a373fec, 0x4724bd4189bd5eac}, // 1e103 * 2**-215
- {0xb2977ee300c50fe7, 0x58edec91ec2cb657}, // 1e104 * 2**-218
- {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed}, // 1e105 * 2**-221
- {0x8b865b215899f46c, 0xbd79e0d20082ee74}, // 1e106 * 2**-225
- {0xae67f1e9aec07187, 0xecd8590680a3aa11}, // 1e107 * 2**-228
- {0xda01ee641a708de9, 0xe80e6f4820cc9495}, // 1e108 * 2**-231
- {0x884134fe908658b2, 0x3109058d147fdcdd}, // 1e109 * 2**-235
- {0xaa51823e34a7eede, 0xbd4b46f0599fd415}, // 1e110 * 2**-238
- {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a}, // 1e111 * 2**-241
- {0x850fadc09923329e, 0x03e2cf6bc604ddb0}, // 1e112 * 2**-245
- {0xa6539930bf6bff45, 0x84db8346b786151c}, // 1e113 * 2**-248
- {0xcfe87f7cef46ff16, 0xe612641865679a63}, // 1e114 * 2**-251
- {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e}, // 1e115 * 2**-255
- {0xa26da3999aef7749, 0xe3be5e330f38f09d}, // 1e116 * 2**-258
- {0xcb090c8001ab551c, 0x5cadf5bfd3072cc5}, // 1e117 * 2**-261
- {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6}, // 1e118 * 2**-264
- {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa}, // 1e119 * 2**-268
- {0xc646d63501a1511d, 0xb281e1fd541501b8}, // 1e120 * 2**-271
- {0xf7d88bc24209a565, 0x1f225a7ca91a4226}, // 1e121 * 2**-274
- {0x9ae757596946075f, 0x3375788de9b06958}, // 1e122 * 2**-278
- {0xc1a12d2fc3978937, 0x0052d6b1641c83ae}, // 1e123 * 2**-281
- {0xf209787bb47d6b84, 0xc0678c5dbd23a49a}, // 1e124 * 2**-284
- {0x9745eb4d50ce6332, 0xf840b7ba963646e0}, // 1e125 * 2**-288
- {0xbd176620a501fbff, 0xb650e5a93bc3d898}, // 1e126 * 2**-291
- {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe}, // 1e127 * 2**-294
- {0x93ba47c980e98cdf, 0xc66f336c36b10137}, // 1e128 * 2**-298
- {0xb8a8d9bbe123f017, 0xb80b0047445d4184}, // 1e129 * 2**-301
- {0xe6d3102ad96cec1d, 0xa60dc059157491e5}, // 1e130 * 2**-304
- {0x9043ea1ac7e41392, 0x87c89837ad68db2f}, // 1e131 * 2**-308
- {0xb454e4a179dd1877, 0x29babe4598c311fb}, // 1e132 * 2**-311
- {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a}, // 1e133 * 2**-314
- {0x8ce2529e2734bb1d, 0x1899e4a65f58660c}, // 1e134 * 2**-318
- {0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f}, // 1e135 * 2**-321
- {0xdc21a1171d42645d, 0x76707543f4fa1f73}, // 1e136 * 2**-324
- {0x899504ae72497eba, 0x6a06494a791c53a8}, // 1e137 * 2**-328
- {0xabfa45da0edbde69, 0x0487db9d17636892}, // 1e138 * 2**-331
- {0xd6f8d7509292d603, 0x45a9d2845d3c42b6}, // 1e139 * 2**-334
- {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2}, // 1e140 * 2**-338
- {0xa7f26836f282b732, 0x8e6cac7768d7141e}, // 1e141 * 2**-341
- {0xd1ef0244af2364ff, 0x3207d795430cd926}, // 1e142 * 2**-344
- {0x8335616aed761f1f, 0x7f44e6bd49e807b8}, // 1e143 * 2**-348
- {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6}, // 1e144 * 2**-351
- {0xcd036837130890a1, 0x36dba887c37a8c0f}, // 1e145 * 2**-354
- {0x802221226be55a64, 0xc2494954da2c9789}, // 1e146 * 2**-358
- {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c}, // 1e147 * 2**-361
- {0xc83553c5c8965d3d, 0x6f92829494e5acc7}, // 1e148 * 2**-364
- {0xfa42a8b73abbf48c, 0xcb772339ba1f17f9}, // 1e149 * 2**-367
- {0x9c69a97284b578d7, 0xff2a760414536efb}, // 1e150 * 2**-371
- {0xc38413cf25e2d70d, 0xfef5138519684aba}, // 1e151 * 2**-374
- {0xf46518c2ef5b8cd1, 0x7eb258665fc25d69}, // 1e152 * 2**-377
- {0x98bf2f79d5993802, 0xef2f773ffbd97a61}, // 1e153 * 2**-381
- {0xbeeefb584aff8603, 0xaafb550ffacfd8fa}, // 1e154 * 2**-384
- {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38}, // 1e155 * 2**-387
- {0x952ab45cfa97a0b2, 0xdd945a747bf26183}, // 1e156 * 2**-391
- {0xba756174393d88df, 0x94f971119aeef9e4}, // 1e157 * 2**-394
- {0xe912b9d1478ceb17, 0x7a37cd5601aab85d}, // 1e158 * 2**-397
- {0x91abb422ccb812ee, 0xac62e055c10ab33a}, // 1e159 * 2**-401
- {0xb616a12b7fe617aa, 0x577b986b314d6009}, // 1e160 * 2**-404
- {0xe39c49765fdf9d94, 0xed5a7e85fda0b80b}, // 1e161 * 2**-407
- {0x8e41ade9fbebc27d, 0x14588f13be847307}, // 1e162 * 2**-411
- {0xb1d219647ae6b31c, 0x596eb2d8ae258fc8}, // 1e163 * 2**-414
- {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb}, // 1e164 * 2**-417
- {0x8aec23d680043bee, 0x25de7bb9480d5854}, // 1e165 * 2**-421
- {0xada72ccc20054ae9, 0xaf561aa79a10ae6a}, // 1e166 * 2**-424
- {0xd910f7ff28069da4, 0x1b2ba1518094da04}, // 1e167 * 2**-427
- {0x87aa9aff79042286, 0x90fb44d2f05d0842}, // 1e168 * 2**-431
- {0xa99541bf57452b28, 0x353a1607ac744a53}, // 1e169 * 2**-434
- {0xd3fa922f2d1675f2, 0x42889b8997915ce8}, // 1e170 * 2**-437
- {0x847c9b5d7c2e09b7, 0x69956135febada11}, // 1e171 * 2**-441
- {0xa59bc234db398c25, 0x43fab9837e699095}, // 1e172 * 2**-444
- {0xcf02b2c21207ef2e, 0x94f967e45e03f4bb}, // 1e173 * 2**-447
- {0x8161afb94b44f57d, 0x1d1be0eebac278f5}, // 1e174 * 2**-451
- {0xa1ba1ba79e1632dc, 0x6462d92a69731732}, // 1e175 * 2**-454
- {0xca28a291859bbf93, 0x7d7b8f7503cfdcfe}, // 1e176 * 2**-457
- {0xfcb2cb35e702af78, 0x5cda735244c3d43e}, // 1e177 * 2**-460
- {0x9defbf01b061adab, 0x3a0888136afa64a7}, // 1e178 * 2**-464
- {0xc56baec21c7a1916, 0x088aaa1845b8fdd0}, // 1e179 * 2**-467
- {0xf6c69a72a3989f5b, 0x8aad549e57273d45}, // 1e180 * 2**-470
- {0x9a3c2087a63f6399, 0x36ac54e2f678864b}, // 1e181 * 2**-474
- {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd}, // 1e182 * 2**-477
- {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5}, // 1e183 * 2**-480
- {0x969eb7c47859e743, 0x9f644ae5a4b1b325}, // 1e184 * 2**-484
- {0xbc4665b596706114, 0x873d5d9f0dde1fee}, // 1e185 * 2**-487
- {0xeb57ff22fc0c7959, 0xa90cb506d155a7ea}, // 1e186 * 2**-490
- {0x9316ff75dd87cbd8, 0x09a7f12442d588f2}, // 1e187 * 2**-494
- {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb2f}, // 1e188 * 2**-497
- {0xe5d3ef282a242e81, 0x8f1668c8a86da5fa}, // 1e189 * 2**-500
- {0x8fa475791a569d10, 0xf96e017d694487bc}, // 1e190 * 2**-504
- {0xb38d92d760ec4455, 0x37c981dcc395a9ac}, // 1e191 * 2**-507
- {0xe070f78d3927556a, 0x85bbe253f47b1417}, // 1e192 * 2**-510
- {0x8c469ab843b89562, 0x93956d7478ccec8e}, // 1e193 * 2**-514
- {0xaf58416654a6babb, 0x387ac8d1970027b2}, // 1e194 * 2**-517
- {0xdb2e51bfe9d0696a, 0x06997b05fcc0319e}, // 1e195 * 2**-520
- {0x88fcf317f22241e2, 0x441fece3bdf81f03}, // 1e196 * 2**-524
- {0xab3c2fddeeaad25a, 0xd527e81cad7626c3}, // 1e197 * 2**-527
- {0xd60b3bd56a5586f1, 0x8a71e223d8d3b074}, // 1e198 * 2**-530
- {0x85c7056562757456, 0xf6872d5667844e49}, // 1e199 * 2**-534
- {0xa738c6bebb12d16c, 0xb428f8ac016561db}, // 1e200 * 2**-537
- {0xd106f86e69d785c7, 0xe13336d701beba52}, // 1e201 * 2**-540
- {0x82a45b450226b39c, 0xecc0024661173473}, // 1e202 * 2**-544
- {0xa34d721642b06084, 0x27f002d7f95d0190}, // 1e203 * 2**-547
- {0xcc20ce9bd35c78a5, 0x31ec038df7b441f4}, // 1e204 * 2**-550
- {0xff290242c83396ce, 0x7e67047175a15271}, // 1e205 * 2**-553
- {0x9f79a169bd203e41, 0x0f0062c6e984d386}, // 1e206 * 2**-557
- {0xc75809c42c684dd1, 0x52c07b78a3e60868}, // 1e207 * 2**-560
- {0xf92e0c3537826145, 0xa7709a56ccdf8a82}, // 1e208 * 2**-563
- {0x9bbcc7a142b17ccb, 0x88a66076400bb691}, // 1e209 * 2**-567
- {0xc2abf989935ddbfe, 0x6acff893d00ea435}, // 1e210 * 2**-570
- {0xf356f7ebf83552fe, 0x0583f6b8c4124d43}, // 1e211 * 2**-573
- {0x98165af37b2153de, 0xc3727a337a8b704a}, // 1e212 * 2**-577
- {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c}, // 1e213 * 2**-580
- {0xeda2ee1c7064130c, 0x1162def06f79df73}, // 1e214 * 2**-583
- {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8}, // 1e215 * 2**-587
- {0xb9a74a0637ce2ee1, 0x6d953e2bd7173692}, // 1e216 * 2**-590
- {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437}, // 1e217 * 2**-593
- {0x910ab1d4db9914a0, 0x1d9c9892400a22a2}, // 1e218 * 2**-597
- {0xb54d5e4a127f59c8, 0x2503beb6d00cab4b}, // 1e219 * 2**-600
- {0xe2a0b5dc971f303a, 0x2e44ae64840fd61d}, // 1e220 * 2**-603
- {0x8da471a9de737e24, 0x5ceaecfed289e5d2}, // 1e221 * 2**-607
- {0xb10d8e1456105dad, 0x7425a83e872c5f47}, // 1e222 * 2**-610
- {0xdd50f1996b947518, 0xd12f124e28f77719}, // 1e223 * 2**-613
- {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f}, // 1e224 * 2**-617
- {0xace73cbfdc0bfb7b, 0x636cc64d1001550b}, // 1e225 * 2**-620
- {0xd8210befd30efa5a, 0x3c47f7e05401aa4e}, // 1e226 * 2**-623
- {0x8714a775e3e95c78, 0x65acfaec34810a71}, // 1e227 * 2**-627
- {0xa8d9d1535ce3b396, 0x7f1839a741a14d0d}, // 1e228 * 2**-630
- {0xd31045a8341ca07c, 0x1ede48111209a050}, // 1e229 * 2**-633
- {0x83ea2b892091e44d, 0x934aed0aab460432}, // 1e230 * 2**-637
- {0xa4e4b66b68b65d60, 0xf81da84d5617853f}, // 1e231 * 2**-640
- {0xce1de40642e3f4b9, 0x36251260ab9d668e}, // 1e232 * 2**-643
- {0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019}, // 1e233 * 2**-647
- {0xa1075a24e4421730, 0xb24cf65b8612f81f}, // 1e234 * 2**-650
- {0xc94930ae1d529cfc, 0xdee033f26797b627}, // 1e235 * 2**-653
- {0xfb9b7cd9a4a7443c, 0x169840ef017da3b1}, // 1e236 * 2**-656
- {0x9d412e0806e88aa5, 0x8e1f289560ee864e}, // 1e237 * 2**-660
- {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2}, // 1e238 * 2**-663
- {0xf5b5d7ec8acb58a2, 0xae10af696774b1db}, // 1e239 * 2**-666
- {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29}, // 1e240 * 2**-670
- {0xbff610b0cc6edd3f, 0x17fd090a58d32af3}, // 1e241 * 2**-673
- {0xeff394dcff8a948e, 0xddfc4b4cef07f5b0}, // 1e242 * 2**-676
- {0x95f83d0a1fb69cd9, 0x4abdaf101564f98e}, // 1e243 * 2**-680
- {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1}, // 1e244 * 2**-683
- {0xea53df5fd18d5513, 0x84c86189216dc5ed}, // 1e245 * 2**-686
- {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4}, // 1e246 * 2**-690
- {0xb7118682dbb66a77, 0x3fbc8c33221dc2a1}, // 1e247 * 2**-693
- {0xe4d5e82392a40515, 0x0fabaf3feaa5334a}, // 1e248 * 2**-696
- {0x8f05b1163ba6832d, 0x29cb4d87f2a7400e}, // 1e249 * 2**-700
- {0xb2c71d5bca9023f8, 0x743e20e9ef511012}, // 1e250 * 2**-703
- {0xdf78e4b2bd342cf6, 0x914da9246b255416}, // 1e251 * 2**-706
- {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e}, // 1e252 * 2**-710
- {0xae9672aba3d0c320, 0xa184ac2473b529b1}, // 1e253 * 2**-713
- {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e}, // 1e254 * 2**-716
- {0x8865899617fb1871, 0x7e2fa67c7a658892}, // 1e255 * 2**-720
- {0xaa7eebfb9df9de8d, 0xddbb901b98feeab7}, // 1e256 * 2**-723
- {0xd51ea6fa85785631, 0x552a74227f3ea565}, // 1e257 * 2**-726
- {0x8533285c936b35de, 0xd53a88958f87275f}, // 1e258 * 2**-730
- {0xa67ff273b8460356, 0x8a892abaf368f137}, // 1e259 * 2**-733
- {0xd01fef10a657842c, 0x2d2b7569b0432d85}, // 1e260 * 2**-736
- {0x8213f56a67f6b29b, 0x9c3b29620e29fc73}, // 1e261 * 2**-740
- {0xa298f2c501f45f42, 0x8349f3ba91b47b8f}, // 1e262 * 2**-743
- {0xcb3f2f7642717713, 0x241c70a936219a73}, // 1e263 * 2**-746
- {0xfe0efb53d30dd4d7, 0xed238cd383aa0110}, // 1e264 * 2**-749
- {0x9ec95d1463e8a506, 0xf4363804324a40aa}, // 1e265 * 2**-753
- {0xc67bb4597ce2ce48, 0xb143c6053edcd0d5}, // 1e266 * 2**-756
- {0xf81aa16fdc1b81da, 0xdd94b7868e94050a}, // 1e267 * 2**-759
- {0x9b10a4e5e9913128, 0xca7cf2b4191c8326}, // 1e268 * 2**-763
- {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0}, // 1e269 * 2**-766
- {0xf24a01a73cf2dccf, 0xbc633b39673c8cec}, // 1e270 * 2**-769
- {0x976e41088617ca01, 0xd5be0503e085d813}, // 1e271 * 2**-773
- {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18}, // 1e272 * 2**-776
- {0xec9c459d51852ba2, 0xddf8e7d60ed1219e}, // 1e273 * 2**-779
- {0x93e1ab8252f33b45, 0xcabb90e5c942b503}, // 1e274 * 2**-783
- {0xb8da1662e7b00a17, 0x3d6a751f3b936243}, // 1e275 * 2**-786
- {0xe7109bfba19c0c9d, 0x0cc512670a783ad4}, // 1e276 * 2**-789
- {0x906a617d450187e2, 0x27fb2b80668b24c5}, // 1e277 * 2**-793
- {0xb484f9dc9641e9da, 0xb1f9f660802dedf6}, // 1e278 * 2**-796
- {0xe1a63853bbd26451, 0x5e7873f8a0396973}, // 1e279 * 2**-799
- {0x8d07e33455637eb2, 0xdb0b487b6423e1e8}, // 1e280 * 2**-803
- {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62}, // 1e281 * 2**-806
- {0xdc5c5301c56b75f7, 0x7641a140cc7810fb}, // 1e282 * 2**-809
- {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d}, // 1e283 * 2**-813
- {0xac2820d9623bf429, 0x546345fa9fbdcd44}, // 1e284 * 2**-816
- {0xd732290fbacaf133, 0xa97c177947ad4095}, // 1e285 * 2**-819
- {0x867f59a9d4bed6c0, 0x49ed8eabcccc485d}, // 1e286 * 2**-823
- {0xa81f301449ee8c70, 0x5c68f256bfff5a74}, // 1e287 * 2**-826
- {0xd226fc195c6a2f8c, 0x73832eec6fff3111}, // 1e288 * 2**-829
- {0x83585d8fd9c25db7, 0xc831fd53c5ff7eab}, // 1e289 * 2**-833
- {0xa42e74f3d032f525, 0xba3e7ca8b77f5e55}, // 1e290 * 2**-836
- {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb}, // 1e291 * 2**-839
- {0x80444b5e7aa7cf85, 0x7980d163cf5b81b3}, // 1e292 * 2**-843
- {0xa0555e361951c366, 0xd7e105bcc332621f}, // 1e293 * 2**-846
- {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7}, // 1e294 * 2**-849
- {0xfa856334878fc150, 0xb14f98f6f0feb951}, // 1e295 * 2**-852
- {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3}, // 1e296 * 2**-856
- {0xc3b8358109e84f07, 0x0a862f80ec4700c8}, // 1e297 * 2**-859
- {0xf4a642e14c6262c8, 0xcd27bb612758c0fa}, // 1e298 * 2**-862
- {0x98e7e9cccfbd7dbd, 0x8038d51cb897789c}, // 1e299 * 2**-866
- {0xbf21e44003acdd2c, 0xe0470a63e6bd56c3}, // 1e300 * 2**-869
- {0xeeea5d5004981478, 0x1858ccfce06cac74}, // 1e301 * 2**-872
- {0x95527a5202df0ccb, 0x0f37801e0c43ebc8}, // 1e302 * 2**-876
- {0xbaa718e68396cffd, 0xd30560258f54e6ba}, // 1e303 * 2**-879
- {0xe950df20247c83fd, 0x47c6b82ef32a2069}, // 1e304 * 2**-882
- {0x91d28b7416cdd27e, 0x4cdc331d57fa5441}, // 1e305 * 2**-886
- {0xb6472e511c81471d, 0xe0133fe4adf8e952}, // 1e306 * 2**-889
- {0xe3d8f9e563a198e5, 0x58180fddd97723a6}, // 1e307 * 2**-892
- {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648}, // 1e308 * 2**-896
- {0xb201833b35d63f73, 0x2cd2cc6551e513da}, // 1e309 * 2**-899
- {0xde81e40a034bcf4f, 0xf8077f7ea65e58d1}, // 1e310 * 2**-902
- {0x8b112e86420f6191, 0xfb04afaf27faf782}, // 1e311 * 2**-906
- {0xadd57a27d29339f6, 0x79c5db9af1f9b563}, // 1e312 * 2**-909
- {0xd94ad8b1c7380874, 0x18375281ae7822bc}, // 1e313 * 2**-912
- {0x87cec76f1c830548, 0x8f2293910d0b15b5}, // 1e314 * 2**-916
- {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb22}, // 1e315 * 2**-919
- {0xd433179d9c8cb841, 0x5fa60692a46151eb}, // 1e316 * 2**-922
- {0x849feec281d7f328, 0xdbc7c41ba6bcd333}, // 1e317 * 2**-926
- {0xa5c7ea73224deff3, 0x12b9b522906c0800}, // 1e318 * 2**-929
- {0xcf39e50feae16bef, 0xd768226b34870a00}, // 1e319 * 2**-932
- {0x81842f29f2cce375, 0xe6a1158300d46640}, // 1e320 * 2**-936
- {0xa1e53af46f801c53, 0x60495ae3c1097fd0}, // 1e321 * 2**-939
- {0xca5e89b18b602368, 0x385bb19cb14bdfc4}, // 1e322 * 2**-942
- {0xfcf62c1dee382c42, 0x46729e03dd9ed7b5}, // 1e323 * 2**-945
- {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d1}, // 1e324 * 2**-949
- {0xc5a05277621be293, 0xc7098b7305241885}, // 1e325 * 2**-952
- {0xf70867153aa2db38, 0xb8cbee4fc66d1ea7}, // 1e326 * 2**-955
- {0x9a65406d44a5c903, 0x737f74f1dc043328}, // 1e327 * 2**-959
- {0xc0fe908895cf3b44, 0x505f522e53053ff2}, // 1e328 * 2**-962
- {0xf13e34aabb430a15, 0x647726b9e7c68fef}, // 1e329 * 2**-965
- {0x96c6e0eab509e64d, 0x5eca783430dc19f5}, // 1e330 * 2**-969
- {0xbc789925624c5fe0, 0xb67d16413d132072}, // 1e331 * 2**-972
- {0xeb96bf6ebadf77d8, 0xe41c5bd18c57e88f}, // 1e332 * 2**-975
- {0x933e37a534cbaae7, 0x8e91b962f7b6f159}, // 1e333 * 2**-979
- {0xb80dc58e81fe95a1, 0x723627bbb5a4adb0}, // 1e334 * 2**-982
- {0xe61136f2227e3b09, 0xcec3b1aaa30dd91c}, // 1e335 * 2**-985
- {0x8fcac257558ee4e6, 0x213a4f0aa5e8a7b1}, // 1e336 * 2**-989
- {0xb3bd72ed2af29e1f, 0xa988e2cd4f62d19d}, // 1e337 * 2**-992
- {0xe0accfa875af45a7, 0x93eb1b80a33b8605}, // 1e338 * 2**-995
- {0x8c6c01c9498d8b88, 0xbc72f130660533c3}, // 1e339 * 2**-999
- {0xaf87023b9bf0ee6a, 0xeb8fad7c7f8680b4}, // 1e340 * 2**-1002
- {0xdb68c2ca82ed2a05, 0xa67398db9f6820e1}, // 1e341 * 2**-1005
- {0x892179be91d43a43, 0x88083f8943a1148c}, // 1e342 * 2**-1009
- {0xab69d82e364948d4, 0x6a0a4f6b948959b0}, // 1e343 * 2**-1012
- {0xd6444e39c3db9b09, 0x848ce34679abb01c}, // 1e344 * 2**-1015
- {0x85eab0e41a6940e5, 0xf2d80e0c0c0b4e11}, // 1e345 * 2**-1019
- {0xa7655d1d2103911f, 0x6f8e118f0f0e2195}, // 1e346 * 2**-1022
- {0xd13eb46469447567, 0x4b7195f2d2d1a9fb}, // 1e347 * 2**-1025
-}
diff --git a/src/strconv/testdata/testfp.txt b/src/strconv/testdata/testfp.txt
deleted file mode 100644
index 08d3c4ef09..0000000000
--- a/src/strconv/testdata/testfp.txt
+++ /dev/null
@@ -1,181 +0,0 @@
-# Floating-point conversion test cases.
-# Empty lines and lines beginning with # are ignored.
-# The rest have four fields per line: type, format, input, and output.
-# The input is given either in decimal or binary scientific notation.
-# The output is the string that should be produced by formatting the
-# input with the given format.
-#
-# The formats are as in C's printf, except that %b means print
-# binary scientific notation: NpE = N x 2^E.
-
-# TODO:
-# Powers of 10.
-# Powers of 2.
-# %.20g versions.
-# random sources
-# random targets
-# random targets ± half a ULP
-
-# Difficult boundary cases, derived from tables given in
-# Vern Paxson, A Program for Testing IEEE Decimal-Binary Conversion
-# ftp://ftp.ee.lbl.gov/testbase-report.ps.Z
-
-# Table 1: Stress Inputs for Conversion to 53-bit Binary, < 1/2 ULP
-float64 %b 5e+125 6653062250012735p+365
-float64 %b 69e+267 4705683757438170p+841
-float64 %b 999e-026 6798841691080350p-129
-float64 %b 7861e-034 8975675289889240p-153
-float64 %b 75569e-254 6091718967192243p-880
-float64 %b 928609e-261 7849264900213743p-900
-float64 %b 9210917e+080 8341110837370930p+236
-float64 %b 84863171e+114 4625202867375927p+353
-float64 %b 653777767e+273 5068902999763073p+884
-float64 %b 5232604057e-298 5741343011915040p-1010
-float64 %b 27235667517e-109 6707124626673586p-380
-float64 %b 653532977297e-123 7078246407265384p-422
-float64 %b 3142213164987e-294 8219991337640559p-988
-float64 %b 46202199371337e-072 5224462102115359p-246
-float64 %b 231010996856685e-073 5224462102115359p-247
-float64 %b 9324754620109615e+212 5539753864394442p+705
-float64 %b 78459735791271921e+049 8388176519442766p+166
-float64 %b 272104041512242479e+200 5554409530847367p+670
-float64 %b 6802601037806061975e+198 5554409530847367p+668
-float64 %b 20505426358836677347e-221 4524032052079546p-722
-float64 %b 836168422905420598437e-234 5070963299887562p-760
-float64 %b 4891559871276714924261e+222 6452687840519111p+757
-
-# Table 2: Stress Inputs for Conversion to 53-bit Binary, > 1/2 ULP
-float64 %b 9e-265 8168427841980010p-930
-float64 %b 85e-037 6360455125664090p-169
-float64 %b 623e+100 6263531988747231p+289
-float64 %b 3571e+263 6234526311072170p+833
-float64 %b 81661e+153 6696636728760206p+472
-float64 %b 920657e-023 5975405561110124p-109
-float64 %b 4603285e-024 5975405561110124p-110
-float64 %b 87575437e-309 8452160731874668p-1053
-float64 %b 245540327e+122 4985336549131723p+381
-float64 %b 6138508175e+120 4985336549131723p+379
-float64 %b 83356057653e+193 5986732817132056p+625
-float64 %b 619534293513e+124 4798406992060657p+399
-float64 %b 2335141086879e+218 5419088166961646p+713
-float64 %b 36167929443327e-159 8135819834632444p-536
-float64 %b 609610927149051e-255 4576664294594737p-850
-float64 %b 3743626360493413e-165 6898586531774201p-549
-float64 %b 94080055902682397e-242 6273271706052298p-800
-float64 %b 899810892172646163e+283 7563892574477827p+947
-float64 %b 7120190517612959703e+120 5385467232557565p+409
-float64 %b 25188282901709339043e-252 5635662608542340p-825
-float64 %b 308984926168550152811e-052 5644774693823803p-157
-float64 %b 6372891218502368041059e+064 4616868614322430p+233
-
-# Table 3: Stress Inputs for Converting 53-bit Binary to Decimal, < 1/2 ULP
-float64 %.0e 8511030020275656p-342 9e-88
-float64 %.1e 5201988407066741p-824 4.6e-233
-float64 %.2e 6406892948269899p+237 1.41e+87
-float64 %.3e 8431154198732492p+72 3.981e+37
-float64 %.4e 6475049196144587p+99 4.1040e+45
-float64 %.5e 8274307542972842p+726 2.92084e+234
-float64 %.6e 5381065484265332p-456 2.891946e-122
-float64 %.7e 6761728585499734p-1057 4.3787718e-303
-float64 %.8e 7976538478610756p+376 1.22770163e+129
-float64 %.9e 5982403858958067p+377 1.841552452e+129
-float64 %.10e 5536995190630837p+93 5.4835744350e+43
-float64 %.11e 7225450889282194p+710 3.89190181146e+229
-float64 %.12e 7225450889282194p+709 1.945950905732e+229
-float64 %.13e 8703372741147379p+117 1.4460958381605e+51
-float64 %.14e 8944262675275217p-1001 4.17367747458531e-286
-float64 %.15e 7459803696087692p-707 1.107950772878888e-197
-float64 %.16e 6080469016670379p-381 1.2345501366327440e-99
-float64 %.17e 8385515147034757p+721 9.25031711960365024e+232
-float64 %.18e 7514216811389786p-828 4.198047150284889840e-234
-float64 %.19e 8397297803260511p-345 1.1716315319786511046e-88
-float64 %.20e 6733459239310543p+202 4.32810072844612493629e+76
-float64 %.21e 8091450587292794p-473 3.317710118160031081518e-127
-
-# Table 4: Stress Inputs for Converting 53-bit Binary to Decimal, > 1/2 ULP
-float64 %.0e 6567258882077402p+952 3e+302
-float64 %.1e 6712731423444934p+535 7.6e+176
-float64 %.2e 6712731423444934p+534 3.78e+176
-float64 %.3e 5298405411573037p-957 4.350e-273
-float64 %.4e 5137311167659507p-144 2.3037e-28
-float64 %.5e 6722280709661868p+363 1.26301e+125
-float64 %.6e 5344436398034927p-169 7.142211e-36
-float64 %.7e 8369123604277281p-853 1.3934574e-241
-float64 %.8e 8995822108487663p-780 1.41463449e-219
-float64 %.9e 8942832835564782p-383 4.539277920e-100
-float64 %.10e 8942832835564782p-384 2.2696389598e-100
-float64 %.11e 8942832835564782p-385 1.13481947988e-100
-float64 %.12e 6965949469487146p-249 7.700366561890e-60
-float64 %.13e 6965949469487146p-250 3.8501832809448e-60
-float64 %.14e 6965949469487146p-251 1.92509164047238e-60
-float64 %.15e 7487252720986826p+548 6.898586531774201e+180
-float64 %.16e 5592117679628511p+164 1.3076622631878654e+65
-float64 %.17e 8887055249355788p+665 1.36052020756121240e+216
-float64 %.18e 6994187472632449p+690 3.592810217475959676e+223
-float64 %.19e 8797576579012143p+588 8.9125197712484551899e+192
-float64 %.20e 7363326733505337p+272 5.58769757362301140950e+97
-float64 %.21e 8549497411294502p-448 1.176257830728540379990e-119
-
-# Table 14: Stress Inputs for Conversion to 24-bit Binary, <1/2 ULP
-# NOTE: The lines with exponent p-149 have been changed from the
-# paper. Those entries originally read p-150 and had a mantissa
-# twice as large (and even), but IEEE single-precision has no p-150:
-# that's the start of the denormals.
-float32 %b 5e-20 15474250p-88
-float32 %b 67e+14 12479722p+29
-float32 %b 985e+15 14333636p+36
-# float32 %b 7693e-42 10979816p-150
-float32 %b 7693e-42 5489908p-149
-float32 %b 55895e-16 12888509p-61
-# float32 %b 996622e-44 14224264p-150
-float32 %b 996622e-44 7112132p-149
-float32 %b 7038531e-32 11420669p-107
-# float32 %b 60419369e-46 8623340p-150
-float32 %b 60419369e-46 4311670p-149
-float32 %b 702990899e-20 16209866p-61
-# float32 %b 6930161142e-48 9891056p-150
-float32 %b 6930161142e-48 4945528p-149
-float32 %b 25933168707e+13 14395800p+54
-float32 %b 596428896559e+20 12333860p+82
-
-# Table 15: Stress Inputs for Conversion to 24-bit Binary, >1/2 ULP
-float32 %b 3e-23 9507380p-98
-float32 %b 57e+18 12960300p+42
-float32 %b 789e-35 10739312p-130
-float32 %b 2539e-18 11990089p-72
-float32 %b 76173e+28 9845130p+86
-float32 %b 887745e-11 9760860p-40
-float32 %b 5382571e-37 11447463p-124
-float32 %b 82381273e-35 8554961p-113
-float32 %b 750486563e-38 9975678p-120
-float32 %b 3752432815e-39 9975678p-121
-float32 %b 75224575729e-45 13105970p-137
-float32 %b 459926601011e+15 12466336p+65
-
-# Table 16: Stress Inputs for Converting 24-bit Binary to Decimal, < 1/2 ULP
-float32 %.0e 12676506p-102 2e-24
-float32 %.1e 12676506p-103 1.2e-24
-float32 %.2e 15445013p+86 1.19e+33
-float32 %.3e 13734123p-138 3.941e-35
-float32 %.4e 12428269p-130 9.1308e-33
-float32 %.5e 15334037p-146 1.71900e-37
-float32 %.6e 11518287p-41 5.237910e-06
-float32 %.7e 12584953p-145 2.8216440e-37
-float32 %.8e 15961084p-125 3.75243281e-31
-float32 %.9e 14915817p-146 1.672120916e-37
-float32 %.10e 10845484p-102 2.1388945814e-24
-float32 %.11e 16431059p-61 7.12583594561e-12
-
-# Table 17: Stress Inputs for Converting 24-bit Binary to Decimal, > 1/2 ULP
-float32 %.0e 16093626p+69 1e+28
-float32 %.1e 9983778p+25 3.4e+14
-float32 %.2e 12745034p+104 2.59e+38
-float32 %.3e 12706553p+72 6.001e+28
-float32 %.4e 11005028p+45 3.8721e+20
-float32 %.5e 15059547p+71 3.55584e+28
-float32 %.6e 16015691p-99 2.526831e-23
-float32 %.7e 8667859p+56 6.2458507e+23
-float32 %.8e 14855922p-82 3.07213267e-18
-float32 %.9e 14855922p-83 1.536066333e-18
-float32 %.10e 10144164p-110 7.8147796834e-27
-float32 %.11e 13248074p+95 5.24810279937e+35