comma.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package humanize
  2. import (
  3. "bytes"
  4. "math/big"
  5. "strconv"
  6. "strings"
  7. )
  8. // Comma produces a string form of the given number in base 10 with
  9. // commas after every three orders of magnitude.
  10. //
  11. // e.g. Comma(834142) -> 834,142
  12. func Comma(v int64) string {
  13. sign := ""
  14. if v < 0 {
  15. sign = "-"
  16. v = 0 - v
  17. }
  18. parts := []string{"", "", "", "", "", "", ""}
  19. j := len(parts) - 1
  20. for v > 999 {
  21. parts[j] = strconv.FormatInt(v%1000, 10)
  22. switch len(parts[j]) {
  23. case 2:
  24. parts[j] = "0" + parts[j]
  25. case 1:
  26. parts[j] = "00" + parts[j]
  27. }
  28. v = v / 1000
  29. j--
  30. }
  31. parts[j] = strconv.Itoa(int(v))
  32. return sign + strings.Join(parts[j:], ",")
  33. }
  34. // Commaf produces a string form of the given number in base 10 with
  35. // commas after every three orders of magnitude.
  36. //
  37. // e.g. Comma(834142.32) -> 834,142.32
  38. func Commaf(v float64) string {
  39. buf := &bytes.Buffer{}
  40. if v < 0 {
  41. buf.Write([]byte{'-'})
  42. v = 0 - v
  43. }
  44. comma := []byte{','}
  45. parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
  46. pos := 0
  47. if len(parts[0])%3 != 0 {
  48. pos += len(parts[0]) % 3
  49. buf.WriteString(parts[0][:pos])
  50. buf.Write(comma)
  51. }
  52. for ; pos < len(parts[0]); pos += 3 {
  53. buf.WriteString(parts[0][pos : pos+3])
  54. buf.Write(comma)
  55. }
  56. buf.Truncate(buf.Len() - 1)
  57. if len(parts) > 1 {
  58. buf.Write([]byte{'.'})
  59. buf.WriteString(parts[1])
  60. }
  61. return buf.String()
  62. }
  63. // BigComma produces a string form of the given big.Int in base 10
  64. // with commas after every three orders of magnitude.
  65. func BigComma(b *big.Int) string {
  66. sign := ""
  67. if b.Sign() < 0 {
  68. sign = "-"
  69. b.Abs(b)
  70. }
  71. athousand := big.NewInt(1000)
  72. c := (&big.Int{}).Set(b)
  73. _, m := oom(c, athousand)
  74. parts := make([]string, m+1)
  75. j := len(parts) - 1
  76. mod := &big.Int{}
  77. for b.Cmp(athousand) >= 0 {
  78. b.DivMod(b, athousand, mod)
  79. parts[j] = strconv.FormatInt(mod.Int64(), 10)
  80. switch len(parts[j]) {
  81. case 2:
  82. parts[j] = "0" + parts[j]
  83. case 1:
  84. parts[j] = "00" + parts[j]
  85. }
  86. j--
  87. }
  88. parts[j] = strconv.Itoa(int(b.Int64()))
  89. return sign + strings.Join(parts[j:], ",")
  90. }