Files
YaeMikoBot/utils/humanize.go

109 lines
2.1 KiB
Go

package utils
import (
"fmt"
"log"
"math/big"
"strconv"
"strings"
"github.com/shopspring/decimal"
)
var NumberNames = map[int]string{
1: "тыс.",
2: "млн.",
3: "млрд.",
4: "трлн.",
5: "квадрлн.",
6: "квинтлн.",
7: "секстлн.",
8: "септлн.",
9: "октлн.",
10: "нонилн.",
11: "децилн.",
12: "ундецилн.",
13: "дуодецилн.",
}
func Short(n string) string {
d, err := decimal.NewFromString(n)
if err != nil {
log.Fatalln(err)
}
comma := DecimalComma(&d)
sp := strings.Split(comma, "'")
if len(sp) == 0 {
return ""
}
return fmt.Sprintf("(%s %s)", sp[0], NumberNames[len(sp)-1])
}
// order of magnitude (to a max order)
//func oomm(n, b *big.Int, maxmag int) (float64, int) {
// mag := 0
// m := &big.Int{}
// for n.Cmp(b) >= 0 {
// n.DivMod(n, b, m)
// mag++
// if mag == maxmag && maxmag >= 0 {
// break
// }
// }
// return float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag
//}
// total order of magnitude
// (same as above, but with no upper limit)
func oom(n, b *big.Int) (float64, int) {
mag := 0
m := &big.Int{}
for n.Cmp(b) >= 0 {
n.DivMod(n, b, m)
mag++
}
return float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag
}
func BigComma(b *big.Int) string {
sign := ""
if b.Sign() < 0 {
sign = "-"
b.Abs(b)
}
athousand := big.NewInt(1000)
c := (&big.Int{}).Set(b)
_, m := oom(c, athousand)
parts := make([]string, m+1)
j := len(parts) - 1
mod := &big.Int{}
for b.Cmp(athousand) >= 0 {
b.DivMod(b, athousand, mod)
parts[j] = strconv.FormatInt(mod.Int64(), 10)
switch len(parts[j]) {
case 2:
parts[j] = "0" + parts[j]
case 1:
parts[j] = "00" + parts[j]
}
j--
}
parts[j] = strconv.Itoa(int(b.Int64()))
return sign + strings.Join(parts[j:], "'")
}
func DecimalComma(d *decimal.Decimal) string {
if d.IsInteger() {
return BigComma(d.BigInt())
}
fmt.Println(d.String())
exp := strings.Split(d.String(), ".")[1]
return BigComma(d.BigInt()) + "." + exp
}
func IntComma(i int) string {
return BigComma(big.NewInt(int64(i)))
}