Opened 6 years ago

Closed 6 years ago

Last modified 2 days ago

#30363 closed Cleanup/optimization (fixed)

utils.numberformat.format renders small decimals in exponential notation.

Reported by: Sjoerd Job Postmus Owned by: nobody
Component: Utilities Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using utils.number_format with decimal_pos, extremely small numbers get displayed using exponential notation.

>>> from django.utils.numberformat import format as nformat
>>> nformat(Decimal('1e-199'), '.', decimal_pos=2)
'0.00'
>>> nformat(Decimal('1e-200'), '.', decimal_pos=2)
'1.00e-200'

This is caused by a hardcoded cut-off point in the internal logic, but I would argue that when a decimal_pos argument is supplied and the number to be formatted is smaller in absolute size than what can be encoded using the provided number of decimal positions, the returned string should be 0.0000...000 instead.

Change History (6)

comment:1 by Carlton Gibson, 6 years ago

Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/optimization

Hi Sjoerd.

OK, so this is related to the changes in 9cc6a60040b0f64f8ea066dd215176d4bd16621d.

Happy to Accept as a potential Cleanup/optimization — I guess ultimately it depends on what the change looks like. (i.e. is the nicer behaviour worth the extra complexity? etc)
I'm assuming you're ready/willing to make the patch...?

Thanks!

comment:2 by Sjoerd Job Postmus, 6 years ago

Yes, definitely willing to pick it up as a patch. It should be a fairly minimal addition.

comment:3 by Sjoerd Job Postmus, 6 years ago

Has patch: set

comment:4 by Florian Apolloner <apollo13@…>, 6 years ago

Resolution: fixed
Status: newclosed

In e6d57c4d:

Fixed #30363 -- Do not use exponential notation for small decimal numbers.

In 9cc6a60040b0f64f8ea066dd215176d4bd16621d a security patch was
introduced to prevent allocating large segments of memory when a
very large or very small decimal number was to be formatted.

As a side-effect, there was a change in formatting of small decimal
numbers even when the decimal_pos argument was provided, which meant
that reasonable small decimal numbers (above 1e-199) would be formatted
as 0.00, while smaller decimal numbers (under 1e-200) would be
formatted as 1e-200.

comment:5 by Florian Apolloner <apollo13@…>, 6 years ago

In e6d57c4d:

Fixed #30363 -- Do not use exponential notation for small decimal numbers.

In 9cc6a60040b0f64f8ea066dd215176d4bd16621d a security patch was
introduced to prevent allocating large segments of memory when a
very large or very small decimal number was to be formatted.

As a side-effect, there was a change in formatting of small decimal
numbers even when the decimal_pos argument was provided, which meant
that reasonable small decimal numbers (above 1e-199) would be formatted
as 0.00, while smaller decimal numbers (under 1e-200) would be
formatted as 1e-200.

comment:6 by Suraj, 2 days ago

A pull request has been created to resolve this issue: [PR #18830](https://github.com/django/django/pull/18830)

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