117 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
package humanize
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"math"
 | 
						|
	"math/big"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
)
 | 
						|
 | 
						|
// Comma produces a string form of the given number in base 10 with
 | 
						|
// commas after every three orders of magnitude.
 | 
						|
//
 | 
						|
// e.g. Comma(834142) -> 834,142
 | 
						|
func Comma(v int64) string {
 | 
						|
	sign := ""
 | 
						|
 | 
						|
	// Min int64 can't be negated to a usable value, so it has to be special cased.
 | 
						|
	if v == math.MinInt64 {
 | 
						|
		return "-9,223,372,036,854,775,808"
 | 
						|
	}
 | 
						|
 | 
						|
	if v < 0 {
 | 
						|
		sign = "-"
 | 
						|
		v = 0 - v
 | 
						|
	}
 | 
						|
 | 
						|
	parts := []string{"", "", "", "", "", "", ""}
 | 
						|
	j := len(parts) - 1
 | 
						|
 | 
						|
	for v > 999 {
 | 
						|
		parts[j] = strconv.FormatInt(v%1000, 10)
 | 
						|
		switch len(parts[j]) {
 | 
						|
		case 2:
 | 
						|
			parts[j] = "0" + parts[j]
 | 
						|
		case 1:
 | 
						|
			parts[j] = "00" + parts[j]
 | 
						|
		}
 | 
						|
		v = v / 1000
 | 
						|
		j--
 | 
						|
	}
 | 
						|
	parts[j] = strconv.Itoa(int(v))
 | 
						|
	return sign + strings.Join(parts[j:], ",")
 | 
						|
}
 | 
						|
 | 
						|
// Commaf produces a string form of the given number in base 10 with
 | 
						|
// commas after every three orders of magnitude.
 | 
						|
//
 | 
						|
// e.g. Commaf(834142.32) -> 834,142.32
 | 
						|
func Commaf(v float64) string {
 | 
						|
	buf := &bytes.Buffer{}
 | 
						|
	if v < 0 {
 | 
						|
		buf.Write([]byte{'-'})
 | 
						|
		v = 0 - v
 | 
						|
	}
 | 
						|
 | 
						|
	comma := []byte{','}
 | 
						|
 | 
						|
	parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
 | 
						|
	pos := 0
 | 
						|
	if len(parts[0])%3 != 0 {
 | 
						|
		pos += len(parts[0]) % 3
 | 
						|
		buf.WriteString(parts[0][:pos])
 | 
						|
		buf.Write(comma)
 | 
						|
	}
 | 
						|
	for ; pos < len(parts[0]); pos += 3 {
 | 
						|
		buf.WriteString(parts[0][pos : pos+3])
 | 
						|
		buf.Write(comma)
 | 
						|
	}
 | 
						|
	buf.Truncate(buf.Len() - 1)
 | 
						|
 | 
						|
	if len(parts) > 1 {
 | 
						|
		buf.Write([]byte{'.'})
 | 
						|
		buf.WriteString(parts[1])
 | 
						|
	}
 | 
						|
	return buf.String()
 | 
						|
}
 | 
						|
 | 
						|
// CommafWithDigits works like the Commaf but limits the resulting
 | 
						|
// string to the given number of decimal places.
 | 
						|
//
 | 
						|
// e.g. CommafWithDigits(834142.32, 1) -> 834,142.3
 | 
						|
func CommafWithDigits(f float64, decimals int) string {
 | 
						|
	return stripTrailingDigits(Commaf(f), decimals)
 | 
						|
}
 | 
						|
 | 
						|
// BigComma produces a string form of the given big.Int in base 10
 | 
						|
// with commas after every three orders of magnitude.
 | 
						|
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:], ",")
 | 
						|
}
 |