Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/internal/strconv/atof.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func (b *decimal) set(s string) (ok bool) {
// digits
sawdot := false
sawdigits := false
nd := 0 // number of significant digits
for ; i < len(s); i++ {
switch {
case s[i] == '_':
Expand All @@ -107,15 +108,16 @@ func (b *decimal) set(s string) (ok bool) {
return
}
sawdot = true
b.dp = b.nd
b.dp = nd
continue

case '0' <= s[i] && s[i] <= '9':
sawdigits = true
if s[i] == '0' && b.nd == 0 { // ignore leading zeros
if s[i] == '0' && nd == 0 { // ignore leading zeros
b.dp--
continue
}
nd++
if b.nd < len(b.d) {
b.d[b.nd] = s[i]
b.nd++
Expand All @@ -130,7 +132,7 @@ func (b *decimal) set(s string) (ok bool) {
return
}
if !sawdot {
b.dp = b.nd
b.dp = nd
}

// optional exponent moves decimal point.
Expand Down
12 changes: 12 additions & 0 deletions src/internal/strconv/atof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,15 @@ var atoftests = []atofTest{
{"1.00000000000000011102230246251565404236316680908203125" + strings.Repeat("0", 10000) + "1", "1.0000000000000002", nil},
{"0x1.00000000000008" + strings.Repeat("0", 10000) + "1p0", "1.0000000000000002", nil},

// Integer part longer than the slow path's 800-digit decimal buffer.
{"1" + strings.Repeat("0", 799) + "e-673", "1e+126", nil},
{"1" + strings.Repeat("0", 800) + "e-674", "1e+126", nil},
{"1" + strings.Repeat("0", 826) + "e-700", "1e+126", nil},
{"1" + strings.Repeat("0", 826) + ".5e-700", "1e+126", nil},
// The nonzero tail sets trunc, and d and d+1 round differently near 1e126,
// so the optimized path falls back to the slow path too.
{"1" + strings.Repeat("0", 824) + "1e-699", "1e+126", nil},

// Halfway between x := math.Nextafter(1, 2) and math.Nextafter(x, 2)
// Round to even (up).
{"1.00000000000000033306690738754696212708950042724609375", "1.0000000000000004", nil},
Expand Down Expand Up @@ -371,6 +380,9 @@ var atof32tests = []atofTest{
{"1.000000059604644775390625" + strings.Repeat("0", 10000) + "1", "1.0000001", nil},
{"0x1.000001" + strings.Repeat("0", 10000) + "1p0", "1.0000001", nil},

// Integer part longer than the slow path's 800-digit decimal buffer.
{"1" + strings.Repeat("0", 824) + "1e-795", "1e+30", nil},

// largest float32: (1<<128) * (1 - 2^-24)
{"340282346638528859811704183484516925440", "3.4028235e+38", nil},
{"-340282346638528859811704183484516925440", "-3.4028235e+38", nil},
Expand Down
Loading