diff options
Diffstat (limited to 'vendor/github.com/tdewolff/parse/strconv/float.go')
-rw-r--r-- | vendor/github.com/tdewolff/parse/strconv/float.go | 251 |
1 files changed, 0 insertions, 251 deletions
diff --git a/vendor/github.com/tdewolff/parse/strconv/float.go b/vendor/github.com/tdewolff/parse/strconv/float.go deleted file mode 100644 index da1a30d..0000000 --- a/vendor/github.com/tdewolff/parse/strconv/float.go +++ /dev/null @@ -1,251 +0,0 @@ -package strconv // import "github.com/tdewolff/parse/strconv" - -import "math" - -var float64pow10 = []float64{ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22, -} - -// Float parses a byte-slice and returns the float it represents. -// If an invalid character is encountered, it will stop there. -func ParseFloat(b []byte) (float64, int) { - i := 0 - neg := false - if i < len(b) && (b[i] == '+' || b[i] == '-') { - neg = b[i] == '-' - i++ - } - - dot := -1 - trunk := -1 - n := uint64(0) - for ; i < len(b); i++ { - c := b[i] - if c >= '0' && c <= '9' { - if trunk == -1 { - if n > math.MaxUint64/10 { - trunk = i - } else { - n *= 10 - n += uint64(c - '0') - } - } - } else if dot == -1 && c == '.' { - dot = i - } else { - break - } - } - - f := float64(n) - if neg { - f = -f - } - - mantExp := int64(0) - if dot != -1 { - if trunk == -1 { - trunk = i - } - mantExp = int64(trunk - dot - 1) - } else if trunk != -1 { - mantExp = int64(trunk - i) - } - expExp := int64(0) - if i < len(b) && (b[i] == 'e' || b[i] == 'E') { - i++ - if e, expLen := ParseInt(b[i:]); expLen > 0 { - expExp = e - i += expLen - } - } - exp := expExp - mantExp - - // copied from strconv/atof.go - if exp == 0 { - return f, i - } else if exp > 0 && 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 exp > 22 { - f *= float64pow10[exp-22] - exp = 22 - } - if f <= 1e15 && f >= -1e15 { - return f * float64pow10[exp], i - } - } else if exp < 0 && exp >= -22 { // int / 10^k - return f / float64pow10[-exp], i - } - f *= math.Pow10(int(-mantExp)) - return f * math.Pow10(int(expExp)), i -} - -const log2 = 0.301029995 -const int64maxlen = 18 - -func float64exp(f float64) int { - exp2 := 0 - if f != 0.0 { - x := math.Float64bits(f) - exp2 = int(x>>(64-11-1))&0x7FF - 1023 + 1 - } - - exp10 := float64(exp2) * log2 - if exp10 < 0 { - exp10 -= 1.0 - } - return int(exp10) -} - -func AppendFloat(b []byte, f float64, prec int) ([]byte, bool) { - if math.IsNaN(f) || math.IsInf(f, 0) { - return b, false - } else if prec >= int64maxlen { - return b, false - } - - neg := false - if f < 0.0 { - f = -f - neg = true - } - if prec == -1 { - prec = int64maxlen - 1 - } - prec -= float64exp(f) // number of digits in front of the dot - f *= math.Pow10(prec) - - // calculate mantissa and exponent - mant := int64(f) - mantLen := LenInt(mant) - mantExp := mantLen - prec - 1 - if mant == 0 { - return append(b, '0'), true - } - - // expLen is zero for positive exponents, because positive exponents are determined later on in the big conversion loop - exp := 0 - expLen := 0 - if mantExp > 0 { - // positive exponent is determined in the loop below - // but if we initially decreased the exponent to fit in an integer, we can't set the new exponent in the loop alone, - // since the number of zeros at the end determines the positive exponent in the loop, and we just artificially lost zeros - if prec < 0 { - exp = mantExp - } - expLen = 1 + LenInt(int64(exp)) // e + digits - } else if mantExp < -3 { - exp = mantExp - expLen = 2 + LenInt(int64(exp)) // e + minus + digits - } else if mantExp < -1 { - mantLen += -mantExp - 1 // extra zero between dot and first digit - } - - // reserve space in b - i := len(b) - maxLen := 1 + mantLen + expLen // dot + mantissa digits + exponent - if neg { - maxLen++ - } - if i+maxLen > cap(b) { - b = append(b, make([]byte, maxLen)...) - } else { - b = b[:i+maxLen] - } - - // write to string representation - if neg { - b[i] = '-' - i++ - } - - // big conversion loop, start at the end and move to the front - // initially print trailing zeros and remove them later on - // for example if the first non-zero digit is three positions in front of the dot, it will overwrite the zeros with a positive exponent - zero := true - last := i + mantLen // right-most position of digit that is non-zero + dot - dot := last - prec - exp // position of dot - j := last - for mant > 0 { - if j == dot { - b[j] = '.' - j-- - } - newMant := mant / 10 - digit := mant - 10*newMant - if zero && digit > 0 { - // first non-zero digit, if we are still behind the dot we can trim the end to this position - // otherwise trim to the dot (including the dot) - if j > dot { - i = j + 1 - // decrease negative exponent further to get rid of dot - if exp < 0 { - newExp := exp - (j - dot) - // getting rid of the dot shouldn't lower the exponent to more digits (e.g. -9 -> -10) - if LenInt(int64(newExp)) == LenInt(int64(exp)) { - exp = newExp - dot = j - j-- - i-- - } - } - } else { - i = dot - } - last = j - zero = false - } - b[j] = '0' + byte(digit) - j-- - mant = newMant - } - - if j > dot { - // extra zeros behind the dot - for j > dot { - b[j] = '0' - j-- - } - b[j] = '.' - } else if last+3 < dot { - // add positive exponent because we have 3 or more zeros in front of the dot - i = last + 1 - exp = dot - last - 1 - } else if j == dot { - // handle 0.1 - b[j] = '.' - } - - // exponent - if exp != 0 { - if exp == 1 { - b[i] = '0' - i++ - } else if exp == 2 { - b[i] = '0' - b[i+1] = '0' - i += 2 - } else { - b[i] = 'e' - i++ - if exp < 0 { - b[i] = '-' - i++ - exp = -exp - } - i += LenInt(int64(exp)) - j := i - for exp > 0 { - newExp := exp / 10 - digit := exp - 10*newExp - j-- - b[j] = '0' + byte(digit) - exp = newExp - } - } - } - return b[:i], true -} |