gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

comma.go (2476B)


      1 package humanize
      2 
      3 import (
      4 	"bytes"
      5 	"math"
      6 	"math/big"
      7 	"strconv"
      8 	"strings"
      9 )
     10 
     11 // Comma produces a string form of the given number in base 10 with
     12 // commas after every three orders of magnitude.
     13 //
     14 // e.g. Comma(834142) -> 834,142
     15 func Comma(v int64) string {
     16 	sign := ""
     17 
     18 	// Min int64 can't be negated to a usable value, so it has to be special cased.
     19 	if v == math.MinInt64 {
     20 		return "-9,223,372,036,854,775,808"
     21 	}
     22 
     23 	if v < 0 {
     24 		sign = "-"
     25 		v = 0 - v
     26 	}
     27 
     28 	parts := []string{"", "", "", "", "", "", ""}
     29 	j := len(parts) - 1
     30 
     31 	for v > 999 {
     32 		parts[j] = strconv.FormatInt(v%1000, 10)
     33 		switch len(parts[j]) {
     34 		case 2:
     35 			parts[j] = "0" + parts[j]
     36 		case 1:
     37 			parts[j] = "00" + parts[j]
     38 		}
     39 		v = v / 1000
     40 		j--
     41 	}
     42 	parts[j] = strconv.Itoa(int(v))
     43 	return sign + strings.Join(parts[j:], ",")
     44 }
     45 
     46 // Commaf produces a string form of the given number in base 10 with
     47 // commas after every three orders of magnitude.
     48 //
     49 // e.g. Commaf(834142.32) -> 834,142.32
     50 func Commaf(v float64) string {
     51 	buf := &bytes.Buffer{}
     52 	if v < 0 {
     53 		buf.Write([]byte{'-'})
     54 		v = 0 - v
     55 	}
     56 
     57 	comma := []byte{','}
     58 
     59 	parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
     60 	pos := 0
     61 	if len(parts[0])%3 != 0 {
     62 		pos += len(parts[0]) % 3
     63 		buf.WriteString(parts[0][:pos])
     64 		buf.Write(comma)
     65 	}
     66 	for ; pos < len(parts[0]); pos += 3 {
     67 		buf.WriteString(parts[0][pos : pos+3])
     68 		buf.Write(comma)
     69 	}
     70 	buf.Truncate(buf.Len() - 1)
     71 
     72 	if len(parts) > 1 {
     73 		buf.Write([]byte{'.'})
     74 		buf.WriteString(parts[1])
     75 	}
     76 	return buf.String()
     77 }
     78 
     79 // CommafWithDigits works like the Commaf but limits the resulting
     80 // string to the given number of decimal places.
     81 //
     82 // e.g. CommafWithDigits(834142.32, 1) -> 834,142.3
     83 func CommafWithDigits(f float64, decimals int) string {
     84 	return stripTrailingDigits(Commaf(f), decimals)
     85 }
     86 
     87 // BigComma produces a string form of the given big.Int in base 10
     88 // with commas after every three orders of magnitude.
     89 func BigComma(b *big.Int) string {
     90 	sign := ""
     91 	if b.Sign() < 0 {
     92 		sign = "-"
     93 		b.Abs(b)
     94 	}
     95 
     96 	athousand := big.NewInt(1000)
     97 	c := (&big.Int{}).Set(b)
     98 	_, m := oom(c, athousand)
     99 	parts := make([]string, m+1)
    100 	j := len(parts) - 1
    101 
    102 	mod := &big.Int{}
    103 	for b.Cmp(athousand) >= 0 {
    104 		b.DivMod(b, athousand, mod)
    105 		parts[j] = strconv.FormatInt(mod.Int64(), 10)
    106 		switch len(parts[j]) {
    107 		case 2:
    108 			parts[j] = "0" + parts[j]
    109 		case 1:
    110 			parts[j] = "00" + parts[j]
    111 		}
    112 		j--
    113 	}
    114 	parts[j] = strconv.Itoa(int(b.Int64()))
    115 	return sign + strings.Join(parts[j:], ",")
    116 }