diff --git a/num2words/__init__.py b/num2words/__init__.py index b6969060..88314b4b 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -116,4 +116,10 @@ def num2words(number, ordinal=False, lang='en', to='cardinal', **kwargs): if to not in CONVERTES_TYPES: raise NotImplementedError() + # Float values equal to an integer (e.g. 1.0, 2.0) are valid ordinals; + # convert them to int so to_ordinal_num doesn't embed the decimal point + # in the formatted result (e.g. "1.0st" instead of the correct "1st"). + if to in ('ordinal', 'ordinal_num') and isinstance(number, float) and number == int(number): + number = int(number) + return getattr(converter, 'to_{}'.format(to))(number, **kwargs) diff --git a/tests/test_en.py b/tests/test_en.py index dd80ac0d..39ec52df 100644 --- a/tests/test_en.py +++ b/tests/test_en.py @@ -60,6 +60,10 @@ def test_ordinal_num(self): self.assertEqual(num2words(21, lang='en', to='ordinal_num'), '21st') self.assertEqual(num2words(102, lang='en', to='ordinal_num'), '102nd') self.assertEqual(num2words(73, lang='en', to='ordinal_num'), '73rd') + # integer-valued floats should format without the decimal point + self.assertEqual(num2words(1.0, lang='en', to='ordinal_num'), '1st') + self.assertEqual(num2words(2.0, lang='en', to='ordinal_num'), '2nd') + self.assertEqual(num2words(21.0, lang='en', to='ordinal_num'), '21st') def test_cardinal_for_float_number(self): self.assertEqual(num2words(0.12), "zero point one two")