changeset 52:4df5e8994657

Added round-half-even (banker's rounding) support. Moved a couple of unit-tests from docstrings to a separate file.
author jonas
date Thu, 07 Jun 2007 22:00:43 +0000
parents 3664c93860f1
children 52dbebdd3789
files babel/numbers.py babel/tests/numbers.py
diffstat 2 files changed, 36 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/babel/numbers.py
+++ b/babel/numbers.py
@@ -74,18 +74,16 @@
 def format_decimal(number, format=None, locale=LC_NUMERIC):
     """Returns the given decimal number formatted for a specific locale.
     
-    >>> format_decimal(1, locale='en_US')
-    u'1'
     >>> format_decimal(1.2345, locale='en_US')
     u'1.234'
+    >>> format_decimal(1.2346, locale='en_US')
+    u'1.235'
+    >>> format_decimal(-1.2346, locale='en_US')
+    u'-1.235'
     >>> format_decimal(1.2345, locale='sv_SE')
     u'1,234'
-    >>> format_decimal(12345, locale='de_DE')
+    >>> format_decimal(12345, locale='de')
     u'12.345'
-    >>> format_decimal(-1.2345, format='#,##0.##;-#', locale='sv_SE')
-    u'-1,23'
-    >>> format_decimal(-1.2345, format='#,##0.##;(#)', locale='sv_SE')
-    u'(1,23)'
 
     The appropriate thousands grouping and the decimal separator are used for
     each locale:
@@ -218,7 +216,7 @@
 
 # TODO:
 #  Filling
-#  Rounding
+#  Rounding increment in pattern
 #  Scientific notation
 #  Significant Digits
 def parse_pattern(pattern):
@@ -295,6 +293,7 @@
         self.grouping = grouping
         self.int_precision = int_precision
         self.frac_precision = frac_precision
+        self.format = '%%.%df' % self.frac_precision[1]
         if '%' in ''.join(self.prefix + self.suffix):
             self.scale = 100.0
         elif u'‰' in ''.join(self.prefix + self.suffix):
@@ -308,7 +307,11 @@
     def apply(self, value, locale):
         value *= self.scale
         negative = int(value < 0)
-        a, b = str(value).split('.')
+        a = self.format % value
+        if self.frac_precision[1] > 0:
+            a, b = a.split('.')
+        else:
+            b = ''
         a = a.lstrip('-')
         return '%s%s%s%s' % (self.prefix[negative], 
                              self._format_int(a, locale), 
@@ -334,8 +337,6 @@
         if max == 0 or (min == 0 and int(value) == 0):
             return ''
         width = len(value)
-        if width < min:
-            value += '0' * (min - width)
-        if width > max:
-            value = value[:max] # FIXME: Rounding?!?
+        while len(value) > min and value[-1] == '0':
+            value = value[:-1]
         return get_decimal_symbol(locale) + value
--- a/babel/tests/numbers.py
+++ b/babel/tests/numbers.py
@@ -16,9 +16,31 @@
 
 from babel import numbers
 
+
+class FormatDecimalTestCase(unittest.TestCase):
+
+    def test_subpatterns(self):
+        self.assertEqual(numbers.format_decimal(-12345, '#,##0.##;-#', 
+                         locale='en_US'), '-12,345')
+        self.assertEqual(numbers.format_decimal(-12345, '#,##0.##;(#)', 
+                         locale='en_US'), '(12,345)')
+
+    def test_default_rounding(self):
+        """Testing Round-Half-Even (Banker's rounding)
+        
+        A '5' is rounded to the closest 'even' number
+        """
+        self.assertEqual(numbers.format_decimal(5.5, '0', locale='sv'), '6')
+        self.assertEqual(numbers.format_decimal(6.5, '0', locale='sv'), '6')
+        self.assertEqual(numbers.format_decimal(1.2325, locale='sv'), '1,232')
+        self.assertEqual(numbers.format_decimal(1.2325, locale='sv'), '1,232')
+        self.assertEqual(numbers.format_decimal(1.2335, locale='sv'), '1,234')
+
+
 def suite():
     suite = unittest.TestSuite()
     suite.addTest(doctest.DocTestSuite(numbers))
+    suite.addTest(unittest.makeSuite(FormatDecimalTestCase))
     return suite
 
 if __name__ == '__main__':
Copyright (C) 2012-2017 Edgewall Software