comparison babel/numbers.py @ 50:fa8a27b80eb4

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 3b314a78015d
children 4dcdb1d367ec
comparison
equal deleted inserted replaced
49:daf35e2ad044 50:fa8a27b80eb4
72 return format_decimal(number, locale=locale) 72 return format_decimal(number, locale=locale)
73 73
74 def format_decimal(number, format=None, locale=LC_NUMERIC): 74 def format_decimal(number, format=None, locale=LC_NUMERIC):
75 """Returns the given decimal number formatted for a specific locale. 75 """Returns the given decimal number formatted for a specific locale.
76 76
77 >>> format_decimal(1, locale='en_US')
78 u'1'
79 >>> format_decimal(1.2345, locale='en_US') 77 >>> format_decimal(1.2345, locale='en_US')
80 u'1.234' 78 u'1.234'
79 >>> format_decimal(1.2346, locale='en_US')
80 u'1.235'
81 >>> format_decimal(-1.2346, locale='en_US')
82 u'-1.235'
81 >>> format_decimal(1.2345, locale='sv_SE') 83 >>> format_decimal(1.2345, locale='sv_SE')
82 u'1,234' 84 u'1,234'
83 >>> format_decimal(12345, locale='de_DE') 85 >>> format_decimal(12345, locale='de')
84 u'12.345' 86 u'12.345'
85 >>> format_decimal(-1.2345, format='#,##0.##;-#', locale='sv_SE')
86 u'-1,23'
87 >>> format_decimal(-1.2345, format='#,##0.##;(#)', locale='sv_SE')
88 u'(1,23)'
89 87
90 The appropriate thousands grouping and the decimal separator are used for 88 The appropriate thousands grouping and the decimal separator are used for
91 each locale: 89 each locale:
92 90
93 >>> format_decimal(12345, locale='en_US') 91 >>> format_decimal(12345, locale='en_US')
216 number_re = re.compile(r"%s%s%s" % (PREFIX_PATTERN, NUMBER_PATTERN, 214 number_re = re.compile(r"%s%s%s" % (PREFIX_PATTERN, NUMBER_PATTERN,
217 SUFFIX_PATTERN)) 215 SUFFIX_PATTERN))
218 216
219 # TODO: 217 # TODO:
220 # Filling 218 # Filling
221 # Rounding 219 # Rounding increment in pattern
222 # Scientific notation 220 # Scientific notation
223 # Significant Digits 221 # Significant Digits
224 def parse_pattern(pattern): 222 def parse_pattern(pattern):
225 """Parse number format patterns""" 223 """Parse number format patterns"""
226 if isinstance(pattern, NumberPattern): 224 if isinstance(pattern, NumberPattern):
293 self.prefix = prefix 291 self.prefix = prefix
294 self.suffix = suffix 292 self.suffix = suffix
295 self.grouping = grouping 293 self.grouping = grouping
296 self.int_precision = int_precision 294 self.int_precision = int_precision
297 self.frac_precision = frac_precision 295 self.frac_precision = frac_precision
296 self.format = '%%.%df' % self.frac_precision[1]
298 if '%' in ''.join(self.prefix + self.suffix): 297 if '%' in ''.join(self.prefix + self.suffix):
299 self.scale = 100.0 298 self.scale = 100.0
300 elif u'‰' in ''.join(self.prefix + self.suffix): 299 elif u'‰' in ''.join(self.prefix + self.suffix):
301 self.scale = 1000.0 300 self.scale = 1000.0
302 else: 301 else:
306 return '<%s %r>' % (type(self).__name__, self.pattern) 305 return '<%s %r>' % (type(self).__name__, self.pattern)
307 306
308 def apply(self, value, locale): 307 def apply(self, value, locale):
309 value *= self.scale 308 value *= self.scale
310 negative = int(value < 0) 309 negative = int(value < 0)
311 a, b = str(value).split('.') 310 a = self.format % value
311 if self.frac_precision[1] > 0:
312 a, b = a.split('.')
313 else:
314 b = ''
312 a = a.lstrip('-') 315 a = a.lstrip('-')
313 return '%s%s%s%s' % (self.prefix[negative], 316 return '%s%s%s%s' % (self.prefix[negative],
314 self._format_int(a, locale), 317 self._format_int(a, locale),
315 self._format_frac(b, locale), 318 self._format_frac(b, locale),
316 self.suffix[negative]) 319 self.suffix[negative])
332 def _format_frac(self, value, locale): 335 def _format_frac(self, value, locale):
333 min, max = self.frac_precision 336 min, max = self.frac_precision
334 if max == 0 or (min == 0 and int(value) == 0): 337 if max == 0 or (min == 0 and int(value) == 0):
335 return '' 338 return ''
336 width = len(value) 339 width = len(value)
337 if width < min: 340 while len(value) > min and value[-1] == '0':
338 value += '0' * (min - width) 341 value = value[:-1]
339 if width > max:
340 value = value[:max] # FIXME: Rounding?!?
341 return get_decimal_symbol(locale) + value 342 return get_decimal_symbol(locale) + value
Copyright (C) 2012-2017 Edgewall Software