diff --git a/ordinals.go b/ordinals.go index 43d88a8..e3fe98c 100644 --- a/ordinals.go +++ b/ordinals.go @@ -5,19 +5,28 @@ import "strconv" // Ordinal gives you the input number in a rank/ordinal format. // // Ordinal(3) -> 3rd +// Ordinal(-1) -> -1st func Ordinal(x int) string { + // Suffix selection must use the absolute value because Go's % for + // negative dividends yields a negative remainder (e.g. -1%10 == -1), + // which would never match the positive cases below. + n := x + if n < 0 { + n = -n + } + suffix := "th" - switch x % 10 { + switch n % 10 { case 1: - if x%100 != 11 { + if n%100 != 11 { suffix = "st" } case 2: - if x%100 != 12 { + if n%100 != 12 { suffix = "nd" } case 3: - if x%100 != 13 { + if n%100 != 13 { suffix = "rd" } } diff --git a/ordinals_test.go b/ordinals_test.go index c478d5c..8a51d19 100644 --- a/ordinals_test.go +++ b/ordinals_test.go @@ -24,5 +24,19 @@ func TestOrdinals(t *testing.T) { {"211", Ordinal(211), "211th"}, {"212", Ordinal(212), "212th"}, {"213", Ordinal(213), "213th"}, + // Negatives: Go's % keeps the dividend's sign, so suffix selection + // must use the absolute value. + {"-1", Ordinal(-1), "-1st"}, + {"-2", Ordinal(-2), "-2nd"}, + {"-3", Ordinal(-3), "-3rd"}, + {"-4", Ordinal(-4), "-4th"}, + {"-11", Ordinal(-11), "-11th"}, + {"-12", Ordinal(-12), "-12th"}, + {"-13", Ordinal(-13), "-13th"}, + {"-21", Ordinal(-21), "-21st"}, + {"-22", Ordinal(-22), "-22nd"}, + {"-23", Ordinal(-23), "-23rd"}, + {"-101", Ordinal(-101), "-101st"}, + {"-111", Ordinal(-111), "-111th"}, }.validate(t) }