From: Felix Schwarz Date: Tue, 30 Aug 2011 20:53:33 +0000 (+0000) Subject: Only use bankers round algorithm as a tie breaker if there are two nearest numbers... X-Git-Tag: 1.0~189 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ef5537437355bcb9f20574896acfd1e91e09108;p=thirdparty%2Fbabel.git Only use bankers round algorithm as a tie breaker if there are two nearest numbers, round as usual if there is only one nearest number (#267, patch by Martin) --- diff --git a/ChangeLog b/ChangeLog index a432aaba..2ed745f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,9 @@ http://svn.edgewall.org/repos/babel/tags/1.0.0/ handlers (#227, reported with initial patch by dfraser) * Fix exception if environment contains an invalid locale setting (#200) * use cPickle instead of pickle for better performance (#225) + * Only use bankers round algorithm as a tie breaker if there are two nearest + numbers, round as usual if there is only one nearest number (#267, patch by + Martin) Version 0.9.6 diff --git a/babel/numbers.py b/babel/numbers.py index 62281676..5ea6c381 100644 --- a/babel/numbers.py +++ b/babel/numbers.py @@ -361,6 +361,13 @@ def bankersround(value, ndigits=0): add = 1 elif digits[i] == '5' and digits[i-1] in '13579': add = 1 + elif digits[i] == '5': # previous digit is even + # We round up unless all following digits are zero. + for j in xrange(i + 1, len(digits)): + if digits[j] != '0': + add = 1 + break + scale = 10**ndigits if isinstance(value, Decimal): return Decimal(int(value * scale + add)) / scale * sign diff --git a/babel/tests/numbers.py b/babel/tests/numbers.py index bd7958ac..f4d1d4e3 100644 --- a/babel/tests/numbers.py +++ b/babel/tests/numbers.py @@ -12,7 +12,6 @@ # history and logs, available at http://babel.edgewall.org/log/. from decimal import Decimal - import doctest import unittest @@ -137,10 +136,24 @@ class FormatDecimalTestCase(unittest.TestCase): self.assertEqual(fmt, '0E0') +class BankersRoundTestCase(unittest.TestCase): + def test_round_to_nearest_integer(self): + self.assertEqual(1, numbers.bankersround(Decimal('0.5001'))) + + def test_round_to_even_for_two_nearest_integers(self): + self.assertEqual(0, numbers.bankersround(Decimal('0.5'))) + self.assertEqual(2, numbers.bankersround(Decimal('1.5'))) + self.assertEqual(-2, numbers.bankersround(Decimal('-2.5'))) + + self.assertEqual(0, numbers.bankersround(Decimal('0.05'), ndigits=1)) + self.assertEqual(Decimal('0.2'), numbers.bankersround(Decimal('0.15'), ndigits=1)) + + def suite(): suite = unittest.TestSuite() suite.addTest(doctest.DocTestSuite(numbers)) suite.addTest(unittest.makeSuite(FormatDecimalTestCase)) + suite.addTest(unittest.makeSuite(BankersRoundTestCase)) return suite if __name__ == '__main__':