diff --git a/format/format.go b/format/format.go index 8fd2defa..31059578 100644 --- a/format/format.go +++ b/format/format.go @@ -13,12 +13,20 @@ const ( func HumanNumber(b uint64) string { switch { - case b > Billion: - return fmt.Sprintf("%.0fB", math.Round(float64(b)/Billion)) - case b > Million: - return fmt.Sprintf("%.0fM", math.Round(float64(b)/Million)) - case b > Thousand: - return fmt.Sprintf("%.0fK", math.Round(float64(b)/Thousand)) + case b >= Billion: + number := float64(b) / Billion + if number == math.Floor(number) { + return fmt.Sprintf("%.0fB", number) // no decimals if whole number + } + return fmt.Sprintf("%.1fB", number) // one decimal if not a whole number + case b >= Million: + number := float64(b) / Million + if number == math.Floor(number) { + return fmt.Sprintf("%.0fM", number) // no decimals if whole number + } + return fmt.Sprintf("%.2fM", number) // two decimals if not a whole number + case b >= Thousand: + return fmt.Sprintf("%.0fK", float64(b)/Thousand) default: return fmt.Sprintf("%d", b) } diff --git a/format/format_test.go b/format/format_test.go new file mode 100644 index 00000000..1d73c80b --- /dev/null +++ b/format/format_test.go @@ -0,0 +1,34 @@ +package format + +import ( + "testing" +) + +func TestHumanNumber(t *testing.T) { + + type testCase struct { + input uint64 + expected string + } + + testCases := []testCase{ + {0, "0"}, + {1000000, "1M"}, + {125000000, "125M"}, + {500500000, "500.50M"}, + {500550000, "500.55M"}, + {1000000000, "1B"}, + {2800000000, "2.8B"}, + {2850000000, "2.9B"}, + {1000000000000, "1000B"}, + } + + for _, tc := range testCases { + t.Run(tc.expected, func(t *testing.T) { + result := HumanNumber(tc.input) + if result != tc.expected { + t.Errorf("Expected %s, got %s", tc.expected, result) + } + }) + } +}