diff options
Diffstat (limited to 'vendor/github.com/tdewolff/parse/v2/strconv/decimal.go')
-rw-r--r-- | vendor/github.com/tdewolff/parse/v2/strconv/decimal.go | 83 |
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 } |