...

Source file src/github.com/dustin/go-humanize/comma.go

Documentation: github.com/dustin/go-humanize

     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  }
   117  

View as plain text