diff --git a/django/utils/numberformat.py b/django/utils/numberformat.py
index 069f498..603ce1c 100644
a
|
b
|
def format(number, decimal_sep, decimal_pos, grouping=0, thousand_sep=''):
|
14 | 14 | |
15 | 15 | """ |
16 | 16 | use_grouping = settings.USE_L10N and \ |
17 | | settings.USE_THOUSAND_SEPARATOR and grouping |
| 17 | settings.USE_THOUSAND_SEPARATOR and grouping and thousand_sep |
18 | 18 | # Make the common case fast: |
19 | 19 | if isinstance(number, int) and not use_grouping and not decimal_pos: |
20 | 20 | return mark_safe(unicode(number)) |
21 | | # sign |
22 | | if float(number) < 0: |
| 21 | float_number = float(number) |
| 22 | if decimal_pos: |
| 23 | # Need to use %f format string, as unicode(number) can yield |
| 24 | # exponents for sufficiently small numbers. As a bonus, we get |
| 25 | # rounding and right amount of decimal positions directly. |
| 26 | str_number = unicode(('%.' + str(decimal_pos) + 'f') % (num_number)) |
| 27 | else: |
| 28 | # If decimal_pos is not given, use unicode(number), as %f will |
| 29 | # give 6 decimal positions even if the number doesn't have that |
| 30 | # many decimals. |
| 31 | str_number = unicode(number) |
| 32 | if 'e' in str_number: |
| 33 | # The number is either too small and no decimal_pos was given, |
| 34 | # or the number is too big. The number could be converted to |
| 35 | # wanted format, but it is probably better to return it in |
| 36 | # exponent form (need for documentation?) |
| 37 | return str_number |
| 38 | if not use_grouping: |
| 39 | return str_number.replace('.', decimal_sep) |
| 40 | # Using grouping, need to separate sign, int_part, decimal part |
| 41 | if num_number < 0: |
23 | 42 | sign = '-' |
| 43 | str_number = str_number[1:] |
24 | 44 | else: |
25 | 45 | sign = '' |
26 | | str_number = unicode(number) |
27 | | if str_number[0] == '-': |
28 | | str_number = str_number[1:] |
29 | | # decimal part |
30 | | if '.' in str_number: |
| 46 | if decimal_pos or '.' in str_number: |
31 | 47 | int_part, dec_part = str_number.split('.') |
32 | | if decimal_pos: |
33 | | dec_part = dec_part[:decimal_pos] |
| 48 | dec_part = decimal_sep + dec_part |
34 | 49 | else: |
35 | 50 | int_part, dec_part = str_number, '' |
36 | | if decimal_pos: |
37 | | dec_part = dec_part + ('0' * (decimal_pos - len(dec_part))) |
38 | | if dec_part: dec_part = decimal_sep + dec_part |
39 | | # grouping |
40 | | if use_grouping: |
41 | | int_part_gd = '' |
42 | | for cnt, digit in enumerate(int_part[::-1]): |
43 | | if cnt and not cnt % grouping: |
44 | | int_part_gd += thousand_sep |
45 | | int_part_gd += digit |
46 | | int_part = int_part_gd[::-1] |
47 | | return sign + int_part + dec_part |
| 51 | first_part_len = len(int_part) % grouping |
| 52 | full_parts = int_part[first_part_len:] |
| 53 | groups = [full_parts[i:i+grouping] \ |
| 54 | for i in range(0, len(full_parts), grouping)] |
| 55 | if first_part_len > 0: |
| 56 | groups.insert(0, int_part[0:first_part_len]) |
| 57 | return sign + thousand_sep.join(groups) + dec_part |
48 | 58 | |
diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
index 4aa52b6..785b7ec 100644
a
|
b
|
class FormattingTests(TestCase):
|
148 | 148 | """ |
149 | 149 | settings.USE_L10N = True |
150 | 150 | settings.USE_THOUSAND_SEPARATOR = False |
151 | | self.assertEqual(u'66666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')) |
152 | | self.assertEqual(u'66666A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')) |
| 151 | self.assertEqual(u'66666.67', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')) |
| 152 | self.assertEqual(u'66666A7', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')) |
| 153 | # ticket #14317 |
| 154 | self.assertEqual(u'0,00', nformat(0.000000001, decimal_sep=',', decimal_pos=2)) |
153 | 155 | |
154 | 156 | settings.USE_THOUSAND_SEPARATOR = True |
155 | | self.assertEqual(u'66,666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')) |
156 | | self.assertEqual(u'6B6B6B6B6A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')) |
157 | | self.assertEqual(u'-66666.6', nformat(-66666.666, decimal_sep='.', decimal_pos=1)) |
| 157 | self.assertEqual(u'66,666.67', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=',')) |
| 158 | self.assertEqual(u'6B6B6B6B6A7', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B')) |
| 159 | self.assertEqual(u'-66666.7', nformat(-66666.666, decimal_sep='.', decimal_pos=1)) |
158 | 160 | self.assertEqual(u'-66666.0', nformat(int('-66666'), decimal_sep='.', decimal_pos=1)) |
159 | 161 | self.assertEqual(u'10000.0', nformat(self.l, decimal_sep='.', decimal_pos=1)) |
160 | 162 | |