Commit f88b9eee authored by Ramiro Morales's avatar Ramiro Morales
Browse files

[1.2.X] Fixed #11206 -- Ensure that the floatformat template filter doesn't...

[1.2.X] Fixed #11206 -- Ensure that the floatformat template filter doesn't switch to scientific notation when asked to format a zero value with more than six decimal places. Thanks Tai Lee for the report and fix and Facundo Batista for his help when Decimal module expertise was needed.

Backport of [15736] from trunk

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15738 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent de46b668
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -149,9 +149,19 @@ def floatformat(text, arg=-1):
    if p == 0:
        exp = Decimal(1)
    else:
        exp = Decimal('1.0') / (Decimal(10) ** abs(p))
        exp = Decimal(u'1.0') / (Decimal(10) ** abs(p))
    try:
        return mark_safe(formats.number_format(u'%s' % str(d.quantize(exp, ROUND_HALF_UP)), abs(p)))
        # Avoid conversion to scientific notation by accessing `sign`, `digits`
        # and `exponent` from `Decimal.as_tuple()` directly.
        sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP).as_tuple()
        digits = [unicode(digit) for digit in reversed(digits)]
        while len(digits) <= abs(exponent):
            digits.append(u'0')
        digits.insert(-exponent, u'.')
        if sign:
            digits.append(u'-')
        number = u''.join(reversed(digits))
        return mark_safe(formats.number_format(number, abs(p)))
    except InvalidOperation:
        return input_val
floatformat.is_safe = True
+13 −0
Original line number Diff line number Diff line
@@ -29,6 +29,13 @@ class DefaultFiltersTests(unittest.TestCase):
        self.assertEqual(floatformat(u'¿Cómo esta usted?'), u'')
        self.assertEqual(floatformat(None), u'')

        # Check that we're not converting to scientific notation.
        self.assertEqual(floatformat(0, 6), u'0.000000')
        self.assertEqual(floatformat(0, 7), u'0.0000000')
        self.assertEqual(floatformat(0, 10), u'0.0000000000')
        self.assertEqual(floatformat(0.000000000000000000015, 20),
                                     u'0.00000000000000000002')

        pos_inf = float(1e30000)
        self.assertEqual(floatformat(pos_inf), unicode(pos_inf))

@@ -46,6 +53,12 @@ class DefaultFiltersTests(unittest.TestCase):

        self.assertEqual(floatformat(FloatWrapper(11.000001), -2), u'11.00')

    # This would fail because of Python's float handling. Floats with many zeroes
    # after the decimal point should be passed in as another type such as
    # unicode or Decimal.
    #def test_floatformat_fail(self):
    #    self.assertEqual(floatformat(1.00000000000000015, 16), u'1.0000000000000002')

    def test_addslashes(self):
        self.assertEqual(addslashes(u'"double quotes" and \'single quotes\''),
                          u'\\"double quotes\\" and \\\'single quotes\\\'')