summaryrefslogtreecommitdiff
path: root/vendor/github.com/tdewolff/parse/v2/strconv/decimal.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tdewolff/parse/v2/strconv/decimal.go')
-rw-r--r--vendor/github.com/tdewolff/parse/v2/strconv/decimal.go83
1 files changed, 46 insertions, 37 deletions
diff --git a/vendor/github.com/tdewolff/parse/v2/strconv/decimal.go b/vendor/github.com/tdewolff/parse/v2/strconv/decimal.go
index fc3baf608..8427cb4ac 100644
--- a/vendor/github.com/tdewolff/parse/v2/strconv/decimal.go
+++ b/vendor/github.com/tdewolff/parse/v2/strconv/decimal.go
@@ -4,60 +4,69 @@ import (
"math"
)
+// ParseDecimal parses number of the format 1.2
func ParseDecimal(b []byte) (float64, int) {
+ // float64 has up to 17 significant decimal digits and an exponent in [-1022,1023]
i := 0
- start := i
+ //sign := 1.0
+ //if 0 < len(b) && b[0] == '-' {
+ // sign = -1.0
+ // i++
+ //}
+
+ start := -1
dot := -1
- trunk := -1
n := uint64(0)
for ; i < len(b); i++ {
+ // parse up to 18 significant digits (with dot will be 17) ignoring zeros before/after
c := b[i]
if '0' <= c && c <= '9' {
- if trunk == -1 {
- if math.MaxUint64/10 < n {
- trunk = i
- } else {
- n *= 10
- n += uint64(c - '0')
+ if start == -1 {
+ if '1' <= c && c <= '9' {
+ n = uint64(c - '0')
+ start = i
}
+ } else if i-start < 18 {
+ n *= 10
+ n += uint64(c - '0')
+ }
+ } else if c == '.' {
+ if dot != -1 {
+ break
}
- } else if dot == -1 && c == '.' {
dot = i
} else {
break
}
}
- if i == start || i == start+1 && dot == start {
- return 0.0, 0
+ if i == 1 && dot == 0 {
+ return 0.0, 0 // only dot
+ } else if start == -1 {
+ return 0.0, i // only zeros and dot
+ } else if dot == -1 {
+ dot = i
}
- f := float64(n)
- mantExp := int64(0)
- if dot != -1 {
- if trunk == -1 {
- trunk = i
- }
- mantExp = int64(trunk - dot - 1)
- } else if trunk != -1 {
- mantExp = int64(trunk - i)
+ exp := (dot - start) - LenUint(n)
+ if dot < start {
+ exp++
+ }
+ if 1023 < exp {
+ return math.Inf(1), i
+ //if sign == 1.0 {
+ // return math.Inf(1), i
+ //} else {
+ // return math.Inf(-1), i
+ //}
+ } else if exp < -1022 {
+ return 0.0, i
}
- exp := -mantExp
- // copied from strconv/atof.go
- if exp == 0 {
- return f, i
- } else if 0 < exp && 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 22 < exp {
- f *= float64pow10[exp-22]
- exp = 22
- }
- if -1e15 <= f && f <= 1e15 {
- return f * float64pow10[exp], i
- }
- } else if exp < 0 && -22 <= exp { // int / 10^k
- return f / float64pow10[-exp], i
+ f := float64(n) // sign * float64(n)
+ if 0 <= exp && exp < 23 {
+ return f * float64pow10[exp], i
+ } else if 23 < exp && exp < 0 {
+ return f / float64pow10[exp], i
}
- return f * math.Pow10(int(-mantExp)), i
+ return f * math.Pow10(exp), i
}