summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/utils/numberformat.py3
-rw-r--r--tests/utils_tests/test_numberformat.py28
2 files changed, 27 insertions, 4 deletions
diff --git a/django/utils/numberformat.py b/django/utils/numberformat.py
index 961a60e37d..3bfdb2ea52 100644
--- a/django/utils/numberformat.py
+++ b/django/utils/numberformat.py
@@ -26,6 +26,9 @@ def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='',
return mark_safe(number)
# sign
sign = ''
+ # Treat potentially very large/small floats as Decimals.
+ if isinstance(number, float) and 'e' in str(number).lower():
+ number = Decimal(str(number))
if isinstance(number, Decimal):
if decimal_pos is not None:
diff --git a/tests/utils_tests/test_numberformat.py b/tests/utils_tests/test_numberformat.py
index 83e7d271b5..201e2cfe87 100644
--- a/tests/utils_tests/test_numberformat.py
+++ b/tests/utils_tests/test_numberformat.py
@@ -55,10 +55,30 @@ class TestNumberFormat(SimpleTestCase):
self.assertEqual(nformat(-2 * int_max, '.'), most_max2.format('-'))
def test_float_numbers(self):
- # A float without a fractional part (3.) results in a ".0" when no
- # decimal_pos is given. Contrast that with the Decimal('3.') case in
- # test_decimal_numbers which doesn't return a fractional part.
- self.assertEqual(nformat(3., '.'), '3.0')
+ tests = [
+ (9e-10, 10, '0.0000000009'),
+ (9e-19, 2, '0.00'),
+ (.00000000000099, 0, '0'),
+ (.00000000000099, 13, '0.0000000000009'),
+ (1e16, None, '10000000000000000'),
+ (1e16, 2, '10000000000000000.00'),
+ # A float without a fractional part (3.) results in a ".0" when no
+ # decimal_pos is given. Contrast that with the Decimal('3.') case
+ # in test_decimal_numbers which doesn't return a fractional part.
+ (3., None, '3.0'),
+ ]
+ for value, decimal_pos, expected_value in tests:
+ with self.subTest(value=value, decimal_pos=decimal_pos):
+ self.assertEqual(nformat(value, '.', decimal_pos), expected_value)
+ # Thousand grouping behavior.
+ self.assertEqual(
+ nformat(1e16, '.', thousand_sep=',', grouping=3, force_grouping=True),
+ '10,000,000,000,000,000',
+ )
+ self.assertEqual(
+ nformat(1e16, '.', decimal_pos=2, thousand_sep=',', grouping=3, force_grouping=True),
+ '10,000,000,000,000,000.00',
+ )
def test_decimal_numbers(self):
self.assertEqual(nformat(Decimal('1234'), '.'), '1234')