Opened 17 years ago

Closed 16 years ago

#3004 closed enhancement (fixed)

[patch] add precision argument to floatformat from default filters

Reported by: real.human@… Owned by: Adrian Holovaty
Component: Template system Version: dev
Severity: normal Keywords: floatformat precision
Cc: real.human@…, gary.wilson@… Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

updated floatformat and related docs to allow for a precision argument (which defaults to 1).

Attachments (6)

floatformat.diff (1.8 KB ) - added by real.human@… 17 years ago.
floatformat.patch (2.5 KB ) - added by Chris Beaven 17 years ago.
Updated patch, with tests
floatformat.2.diff (1.8 KB ) - added by real.human@… 17 years ago.
floatformat.3.diff (2.2 KB ) - added by real.human@… 17 years ago.
floatformat.4.diff (2.4 KB ) - added by real.human@… 17 years ago.
floatformat.5.diff (2.8 KB ) - added by mrmachine <real.human@…> 17 years ago.

Download all attachments as: .zip

Change History (22)

by real.human@…, 17 years ago

Attachment: floatformat.diff added

comment:1 by anonymous, 17 years ago

Cc: real.human@… added

comment:2 by Chris Beaven, 17 years ago

The following line is incorrect:

return re.sub(r'\.?0+$', '', ('%%.%sf' % precision) % f)

With both precision and f set to 0, you'll return '' instead of '0'

by Chris Beaven, 17 years ago

Attachment: floatformat.patch added

Updated patch, with tests

comment:3 by Chris Beaven, 17 years ago

Ok, my patch fixes the above issue, but I noticed when running against existing tests that this patch changes the existing behaviour.

floatformat(0.007) used to return 0.0, now returns 0. I'm not sure if the original test is correct - if it is, this patch will need to be modified.

by real.human@…, 17 years ago

Attachment: floatformat.2.diff added

comment:4 by real.human@…, 17 years ago

whoops, i just updated my original patch, too (floatformat.2.diff). i also noticed a rounding error in the old version, so now i'm using str() and round() and then stripping trailing periods and zeroes.

comment:5 by Chris Beaven, 17 years ago

Yep, that's even a better solution :)

Put my tests in your diff too. My comments still stand about this changing existing behaviour.

I also noticed rounding errors using string %s but they still came up for me using str(round( (eg: str(round(1.015, 2)))

by real.human@…, 17 years ago

Attachment: floatformat.3.diff added

comment:6 by real.human@…, 17 years ago

floatformat.3.diff includes your regression test changes.

i also noticed that in the old behaviour, floatformat(0.0) would return '0', but floatformat(0.007) would return '0.0'. as the behaviour so far has been to strip trailing zeroes, i think we should also to strip trailing periods to remove this inconsistency. if anyone wants to keep trailing periods and zeroes, they can use the stringformat filter.

about the rounding error, the old behaviour which uses python's string formatting rounds up for .6 but down for .5, while round() goes up for .5 and down for .4, which i believe is correct. if that's true, is this a bug in python's string formatting?

>>> '%.1f' % 0.15
'0.1'
>>> '%.1f' % 0.16
'0.2'
>>> round(0.14, 1)
0.10000000000000001
>>> round(0.15, 1)
0.20000000000000001
>>> str(round(0.14, 1))
'0.1'
>>> str(round(0.15, 1))
'0.2'

comment:7 by Chris Beaven, 17 years ago

Yes, it's a rounding error in Python's string formatting. Like I said in my example, str(round()) doesn't fix everything:

>>> str(round(1.015, 2))
'1.01'

comment:8 by Chris Beaven, 17 years ago

And you still haven't included the new tests in your diff!

by real.human@…, 17 years ago

Attachment: floatformat.4.diff added

by mrmachine <real.human@…>, 17 years ago

Attachment: floatformat.5.diff added

comment:9 by mrmachine <real.human@…>, 17 years ago

6th time's a charm. tests should be in the diff now, and i've used the decimal module to round the input accurately.

comment:10 by Gary Wilson <gary.wilson@…>, 17 years ago

Cc: gary.wilson@… added

comment:11 by Chris Beaven, 17 years ago

Hate to tell you this, but decimal is new in 2.4. Django needs Python 2.3 compatibility.

comment:12 by mrmachine <real dot human at mrmachine dot net>, 17 years ago

bummer. well, we can just use floatformat.4.diff and live with the rounding errors (unless there is another alternative).

comment:13 by Eric Floehr <eric@…>, 17 years ago

Created ticket #3176 as an alternative implementation to this.

comment:14 by Chris Beaven, 17 years ago

Resolution: fixed
Status: newclosed

Implemented in [4274]

comment:15 by Mark Riedesel <mriedesel@…>, 16 years ago

Resolution: fixed
Status: closedreopened
Version: SVN

I see this bug was fixed almost a year ago, but it seems like either it's broken again or I'm using it improperly. The value I'm passing to the filter is 18.125, if I use floatformat:2 the result is 18.12 instead of the expected 18.13. Tested with SVN revision 6483 (Sept 13th, 2007)

comment:16 by Chris Beaven, 16 years ago

Resolution: fixed
Status: reopenedclosed

This ticket was specifically to introduce a precision argument and that hasn't broken.

The bug you're seeing is a Python rounding problem with float, but we can get around it by using decimal. I opened a new ticket (#5748) now a backwards compatible decimal has been added to Django.

Note: See TracTickets for help on using tickets.
Back to Top