Add a few methods for limiting the number of decimal places outputted. #18
diff --git a/comma.go b/comma.go
index 13611aa..520ae3e 100644
--- a/comma.go
+++ b/comma.go
@@ -76,6 +76,14 @@
 	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 {
diff --git a/comma_test.go b/comma_test.go
index 89daca5..c37a518 100644
--- a/comma_test.go
+++ b/comma_test.go
@@ -36,6 +36,15 @@
 	}.validate(t)
 }
 
+func TestCommafWithDigits(t *testing.T) {
+	testList{
+		{"1.23, 0", CommafWithDigits(1.23, 0), "1"},
+		{"1.23, 1", CommafWithDigits(1.23, 1), "1.2"},
+		{"1.23, 2", CommafWithDigits(1.23, 2), "1.23"},
+		{"1.23, 3", CommafWithDigits(1.23, 3), "1.23"},
+	}.validate(t)
+}
+
 func TestCommafs(t *testing.T) {
 	testList{
 		{"0", Commaf(0), "0"},
diff --git a/ftoa.go b/ftoa.go
index c76190b..1c62b64 100644
--- a/ftoa.go
+++ b/ftoa.go
@@ -1,6 +1,9 @@
 package humanize
 
-import "strconv"
+import (
+	"strconv"
+	"strings"
+)
 
 func stripTrailingZeros(s string) string {
 	offset := len(s) - 1
@@ -17,7 +20,27 @@
 	return s[:offset+1]
 }
 
+func stripTrailingDigits(s string, digits int) string {
+	if i := strings.Index(s, "."); i >= 0 {
+		if digits <= 0 {
+			return s[:i]
+		}
+		i++
+		if i+digits >= len(s) {
+			return s
+		}
+		return s[:i+digits]
+	}
+	return s
+}
+
 // Ftoa converts a float to a string with no trailing zeros.
 func Ftoa(num float64) string {
 	return stripTrailingZeros(strconv.FormatFloat(num, 'f', 6, 64))
 }
+
+// FtoaWithDigits converts a float to a string but limits the resulting string
+// to the given number of decimal places, and no trailing zeros.
+func FtoaWithDigits(num float64, digits int) string {
+	return stripTrailingZeros(stripTrailingDigits(strconv.FormatFloat(num, 'f', 6, 64), digits))
+}
diff --git a/ftoa_test.go b/ftoa_test.go
index 276d411..e5076c4 100644
--- a/ftoa_test.go
+++ b/ftoa_test.go
@@ -17,6 +17,15 @@
 	}.validate(t)
 }
 
+func TestFtoaWithDigits(t *testing.T) {
+	testList{
+		{"1.23, 0", FtoaWithDigits(1.23, 0), "1"},
+		{"1.23, 1", FtoaWithDigits(1.23, 1), "1.2"},
+		{"1.23, 2", FtoaWithDigits(1.23, 2), "1.23"},
+		{"1.23, 3", FtoaWithDigits(1.23, 3), "1.23"},
+	}.validate(t)
+}
+
 func BenchmarkFtoaRegexTrailing(b *testing.B) {
 	trailingZerosRegex := regexp.MustCompile(`\.?0+$`)
 
diff --git a/si.go b/si.go
index b24e481..ae659e0 100644
--- a/si.go
+++ b/si.go
@@ -93,6 +93,16 @@
 	return Ftoa(value) + " " + prefix + unit
 }
 
+// SIWithDigits works like SI but limits the resulting string to the
+// given number of decimal places.
+//
+// e.g. SIWithDigits(1000000, 0, "B") -> 1 MB
+// e.g. SIWithDigits(2.2345e-12, 2, "F") -> 2.23 pF
+func SIWithDigits(input float64, decimals int, unit string) string {
+	value, prefix := ComputeSI(input)
+	return FtoaWithDigits(value, decimals) + " " + prefix + unit
+}
+
 var errInvalid = errors.New("invalid input")
 
 // ParseSI parses an SI string back into the number and unit.
diff --git a/si_test.go b/si_test.go
index bc5bac6..e15fc69 100644
--- a/si_test.go
+++ b/si_test.go
@@ -94,6 +94,29 @@
 	}
 }
 
+func TestSIWithDigits(t *testing.T) {
+	tests := []struct {
+		name      string
+		num       float64
+		digits    int
+		formatted string
+	}{
+		{"e-12", 2.234e-12, 0, "2 pF"},
+		{"e-12", 2.234e-12, 1, "2.2 pF"},
+		{"e-12", 2.234e-12, 2, "2.23 pF"},
+		{"e-12", 2.234e-12, 3, "2.234 pF"},
+		{"e-12", 2.234e-12, 4, "2.234 pF"},
+	}
+
+	for _, test := range tests {
+		got := SIWithDigits(test.num, test.digits, "F")
+		if got != test.formatted {
+			t.Errorf("On %v (%v), got %v, wanted %v",
+				test.name, test.num, got, test.formatted)
+		}
+	}
+}
+
 func BenchmarkParseSI(b *testing.B) {
 	for i := 0; i < b.N; i++ {
 		ParseSI("2.2346ZB")