mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-03 08:12:25 -06:00
Update dependencies:
- github.com/gin-gonic/gin v1.10.0 -> v1.10.1
- github.com/gin-contrib/sessions v1.10.3 -> v1.10.4
- github.com/jackc/pgx/v5 v5.7.4 -> v5.7.5
- github.com/minio/minio-go/v7 v7.0.91 -> v7.0.92
- github.com/pquerna/otp v1.4.0 -> v1.5.0
- github.com/tdewolff/minify/v2 v2.23.5 -> v2.23.8
- github.com/yuin/goldmark v1.7.11 -> v1.7.12
- go.opentelemetry.io/otel{,/*} v1.35.0 -> v1.36.0
- modernc.org/sqlite v1.37.0 -> v1.37.1
Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4188
Reviewed-by: Daenney <daenney@noreply.codeberg.org>
Co-authored-by: kim <grufwub@gmail.com>
Co-committed-by: kim <grufwub@gmail.com>
149 lines
2.5 KiB
Go
149 lines
2.5 KiB
Go
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 {
|
|
if sign == 1.0 {
|
|
return math.Inf(1), i
|
|
} else {
|
|
return math.Inf(-1), i
|
|
}
|
|
} else if exp < -1022 {
|
|
return 0.0, i
|
|
}
|
|
|
|
f := 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
|
|
}
|
|
|
|
// AppendDecimal appends a float to `b` with `dec` the maximum number of decimals.
|
|
func AppendDecimal(b []byte, f float64, dec int) []byte {
|
|
if math.IsNaN(float64(f)) || math.IsInf(float64(f), 0) {
|
|
return b
|
|
}
|
|
|
|
if dec < 0 || 17 < dec {
|
|
dec = 17
|
|
}
|
|
f *= math.Pow10(dec)
|
|
|
|
// correct rounding
|
|
if 0.0 <= f {
|
|
f += 0.5
|
|
} else {
|
|
f -= 0.5
|
|
}
|
|
|
|
// calculate mantissa and exponent
|
|
num := int64(f)
|
|
if num == 0 {
|
|
return append(b, '0')
|
|
}
|
|
for 0 < dec && num%10 == 0 {
|
|
num /= 10
|
|
dec-- // remove trailing zeros
|
|
}
|
|
|
|
i, n := len(b), LenInt(num)
|
|
if 0 < dec {
|
|
if n < dec {
|
|
n = dec // number has zero after dot
|
|
}
|
|
n++ // dot
|
|
if lim := int64pow10[dec]; 0 < num && num < lim || num < 0 && -lim < num {
|
|
n++ // zero at beginning
|
|
}
|
|
}
|
|
if cap(b) < i+n {
|
|
b = append(b, make([]byte, n)...)
|
|
} else {
|
|
b = b[:i+n]
|
|
}
|
|
|
|
// print sign
|
|
if num < 0 {
|
|
num = -num
|
|
b[i] = '-'
|
|
}
|
|
i += n - 1
|
|
|
|
// print number
|
|
if 0 < dec {
|
|
b[i] = byte(num%10) + '0'
|
|
num /= 10
|
|
dec--
|
|
i--
|
|
for 0 < dec {
|
|
b[i] = byte(num%10) + '0'
|
|
num /= 10
|
|
dec--
|
|
i--
|
|
}
|
|
b[i] = '.'
|
|
i--
|
|
}
|
|
if num == 0 {
|
|
b[i] = '0'
|
|
} else {
|
|
for num != 0 {
|
|
b[i] = byte(num%10) + '0'
|
|
num /= 10
|
|
i--
|
|
}
|
|
}
|
|
return b
|
|
}
|