initial commit
This commit is contained in:
104
utils/humanize.go
Normal file
104
utils/humanize.go
Normal file
@@ -0,0 +1,104 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user