Shove commas into big.Ints
diff --git a/comma.go b/comma.go
index 6ff6e90..cc32d4f 100644
--- a/comma.go
+++ b/comma.go
@@ -1,6 +1,7 @@
package humanize
import (
+ "math/big"
"strconv"
"strings"
)
@@ -32,3 +33,34 @@
parts[j] = strconv.Itoa(int(v))
return sign + strings.Join(parts[j:len(parts)], ",")
}
+
+// 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, 2e10)
+ 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:len(parts)], ",")
+}
diff --git a/comma_test.go b/comma_test.go
index 0d627ce..83465d2 100644
--- a/comma_test.go
+++ b/comma_test.go
@@ -1,6 +1,7 @@
package humanize
import (
+ "math/big"
"testing"
)
@@ -38,3 +39,55 @@
Comma(1234567890)
}
}
+
+func bigComma(i int64) string {
+ return BigComma(big.NewInt(i))
+}
+
+func TestBigCommas(t *testing.T) {
+ testList{
+ {"0", bigComma(0), "0"},
+ {"10", bigComma(10), "10"},
+ {"100", bigComma(100), "100"},
+ {"1,000", bigComma(1000), "1,000"},
+ {"10,000", bigComma(10000), "10,000"},
+ {"100,000", bigComma(100000), "100,000"},
+ {"10,000,000", bigComma(10000000), "10,000,000"},
+ {"10,100,000", bigComma(10100000), "10,100,000"},
+ {"10,010,000", bigComma(10010000), "10,010,000"},
+ {"10,001,000", bigComma(10001000), "10,001,000"},
+ {"123,456,789", bigComma(123456789), "123,456,789"},
+ {"maxint", bigComma(9.223372e+18), "9,223,372,000,000,000,000"},
+ {"minint", bigComma(-9.223372e+18), "-9,223,372,000,000,000,000"},
+ {"-123,456,789", bigComma(-123456789), "-123,456,789"},
+ {"-10,100,000", bigComma(-10100000), "-10,100,000"},
+ {"-10,010,000", bigComma(-10010000), "-10,010,000"},
+ {"-10,001,000", bigComma(-10001000), "-10,001,000"},
+ {"-10,000,000", bigComma(-10000000), "-10,000,000"},
+ {"-100,000", bigComma(-100000), "-100,000"},
+ {"-10,000", bigComma(-10000), "-10,000"},
+ {"-1,000", bigComma(-1000), "-1,000"},
+ {"-100", bigComma(-100), "-100"},
+ {"-10", bigComma(-10), "-10"},
+ }.validate(t)
+}
+
+func TestVeryBigCommas(t *testing.T) {
+ tests := []struct{ in, exp string }{
+ {
+ "84889279597249724975972597249849757294578485",
+ "84,889,279,597,249,724,975,972,597,249,849,757,294,578,485",
+ },
+ {
+ "-84889279597249724975972597249849757294578485",
+ "-84,889,279,597,249,724,975,972,597,249,849,757,294,578,485",
+ },
+ }
+ for _, test := range tests {
+ n, _ := (&big.Int{}).SetString(test.in, 10)
+ got := BigComma(n)
+ if test.exp != got {
+ t.Errorf("Expected %q, got %q", test.exp, got)
+ }
+ }
+}