aboutsummaryrefslogtreecommitdiff
path: root/src/strconv/atof.go
diff options
context:
space:
mode:
authorKatie Hockman <katie@golang.org>2020-12-14 10:03:05 -0500
committerKatie Hockman <katie@golang.org>2020-12-14 10:06:13 -0500
commit0345ede87ee12698988973884cfc0fd3d499dffd (patch)
tree7123cff141ee5661208d2f5f437b8f5252ac7f6a /src/strconv/atof.go
parent4651d6b267818b0e0d128a5443289717c4bb8cbc (diff)
parent0a02371b0576964e81c3b40d328db9a3ef3b031b (diff)
downloadgo-0345ede87ee12698988973884cfc0fd3d499dffd.tar.xz
[dev.fuzz] all: merge master into dev.fuzz
Change-Id: I5d8c8329ccc9d747bd81ade6b1cb7cb8ae2e94b2
Diffstat (limited to 'src/strconv/atof.go')
-rw-r--r--src/strconv/atof.go44
1 files changed, 26 insertions, 18 deletions
diff --git a/src/strconv/atof.go b/src/strconv/atof.go
index 901f27afff..9010a66ca8 100644
--- a/src/strconv/atof.go
+++ b/src/strconv/atof.go
@@ -577,21 +577,25 @@ func atof32(s string) (f float32, n int, err error) {
}
if optimize {
- // Try pure floating-point arithmetic conversion.
+ // 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
}
}
- // Try another fast path.
- ext := new(extFloat)
- if ok := ext.AssignDecimal(mantissa, exp, neg, trunc, &float32info); ok {
- b, ovf := ext.floatBits(&float32info)
- f = math.Float32frombits(uint32(b))
- if ovf {
- err = rangeError(fnParseFloat, s)
+ 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
}
- return f, n, err
}
}
@@ -624,21 +628,25 @@ func atof64(s string) (f float64, n int, err error) {
}
if optimize {
- // Try pure floating-point arithmetic conversion.
+ // 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
}
}
- // Try another fast path.
- ext := new(extFloat)
- if ok := ext.AssignDecimal(mantissa, exp, neg, trunc, &float64info); ok {
- b, ovf := ext.floatBits(&float64info)
- f = math.Float64frombits(b)
- if ovf {
- err = rangeError(fnParseFloat, s)
+ 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
}
- return f, n, err
}
}