summaryrefslogtreecommitdiff
path: root/vendor/github.com/tdewolff/parse/v2/strconv/decimal.go
blob: 8427cb4ac99874c46a5dbe26eea8f54d48af33b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package strconv

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
	//sign := 1.0
	//if 0 < len(b) && b[0] == '-' {
	//	sign = -1.0
	//	i++
	//}

	start := -1
	dot := -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 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
			}
			dot = i
		} else {
			break
		}
	}
	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
	}

	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
	}

	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(exp), i
}