summaryrefslogtreecommitdiff
path: root/src/pkg/strconv/atof.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/strconv/atof.go')
-rw-r--r--src/pkg/strconv/atof.go87
1 files changed, 53 insertions, 34 deletions
diff --git a/src/pkg/strconv/atof.go b/src/pkg/strconv/atof.go
index 86c56f7fd..42fc431db 100644
--- a/src/pkg/strconv/atof.go
+++ b/src/pkg/strconv/atof.go
@@ -12,10 +12,7 @@ package strconv
// 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"
- "os"
-)
+import "math"
var optimize = true // can change for testing
@@ -266,6 +263,18 @@ func (d *decimal) atof32int() float32 {
return f
}
+// Reads a uint64 decimal mantissa, which might be truncated.
+func (d *decimal) atou64() (mant uint64, digits int) {
+ const uint64digits = 19
+ for i, c := range d.d[:d.nd] {
+ if i == uint64digits {
+ return mant, i
+ }
+ mant = 10*mant + uint64(c-'0')
+ }
+ return mant, d.nd
+}
+
// Exact powers of 10.
var float64pow10 = []float64{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
@@ -341,28 +350,16 @@ func (d *decimal) atof32() (f float32, ok bool) {
return
}
-// Atof32 converts the string s to a 32-bit floating-point number.
-//
-// If s is well-formed and near a valid floating point number,
-// Atof32 returns the nearest floating point number rounded
-// using IEEE754 unbiased rounding.
-//
-// The errors that Atof32 returns have concrete type *NumError
-// and include err.Num = s.
-//
-// If s is not syntactically well-formed, Atof32 returns err.Error = os.EINVAL.
-//
-// If s is syntactically well-formed but is more than 1/2 ULP
-// away from the largest floating point number of the given size,
-// Atof32 returns f = ±Inf, err.Error = os.ERANGE.
-func Atof32(s string) (f float32, err os.Error) {
+const fnParseFloat = "ParseFloat"
+
+func atof32(s string) (f float32, err error) {
if val, ok := special(s); ok {
return float32(val), nil
}
var d decimal
if !d.set(s) {
- return 0, &NumError{s, os.EINVAL}
+ return 0, syntaxError(fnParseFloat, s)
}
if optimize {
if f, ok := d.atof32(); ok {
@@ -372,44 +369,66 @@ func Atof32(s string) (f float32, err os.Error) {
b, ovf := d.floatBits(&float32info)
f = math.Float32frombits(uint32(b))
if ovf {
- err = &NumError{s, os.ERANGE}
+ err = rangeError(fnParseFloat, s)
}
return f, err
}
-// Atof64 converts the string s to a 64-bit floating-point number.
-// Except for the type of its result, its definition is the same as that
-// of Atof32.
-func Atof64(s string) (f float64, err os.Error) {
+func atof64(s string) (f float64, err error) {
if val, ok := special(s); ok {
return val, nil
}
var d decimal
if !d.set(s) {
- return 0, &NumError{s, os.EINVAL}
+ return 0, syntaxError(fnParseFloat, s)
}
if optimize {
if f, ok := d.atof64(); ok {
return f, nil
}
+
+ // Try another fast path.
+ ext := new(extFloat)
+ if ok := ext.AssignDecimal(&d); ok {
+ b, ovf := ext.floatBits()
+ f = math.Float64frombits(b)
+ if ovf {
+ err = rangeError(fnParseFloat, s)
+ }
+ return f, err
+ }
}
b, ovf := d.floatBits(&float64info)
f = math.Float64frombits(b)
if ovf {
- err = &NumError{s, os.ERANGE}
+ err = rangeError(fnParseFloat, s)
}
return f, err
}
-// AtofN converts the string s to a 64-bit floating-point number,
-// but it rounds the result assuming that it will be stored in a value
-// of n bits (32 or 64).
-func AtofN(s string, n int) (f float64, err os.Error) {
- if n == 32 {
- f1, err1 := Atof32(s)
+// 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.
+//
+// If s is well-formed and near a valid floating point number,
+// ParseFloat returns the nearest floating point number rounded
+// using IEEE754 unbiased rounding.
+//
+// The errors that ParseFloat returns have concrete type *NumError
+// and include err.Num = s.
+//
+// If s is not syntactically well-formed, ParseFloat returns err.Error = 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.Error = ErrRange.
+func ParseFloat(s string, bitSize int) (f float64, err error) {
+ if bitSize == 32 {
+ f1, err1 := atof32(s)
return float64(f1), err1
}
- f1, err1 := Atof64(s)
+ f1, err1 := atof64(s)
return f1, err1
}