diff options
Diffstat (limited to 'libgo/go/strconv/atof.go')
-rw-r--r-- | libgo/go/strconv/atof.go | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/libgo/go/strconv/atof.go b/libgo/go/strconv/atof.go index 1f1d5ae..1c50057 100644 --- a/libgo/go/strconv/atof.go +++ b/libgo/go/strconv/atof.go @@ -583,21 +583,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 } } @@ -630,21 +634,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 } } |