Skip to content

Bypass number rounding #90

@kdeldycke

Description

@kdeldycke

babel.numbers.format_decimal() and babel.numbers.format_currency() have a built-in banker rounding implemented. See:

babel/babel/numbers.py

Lines 648 to 649 in 3ec7bb1

a, b = split_number(bankersround(abs(value),
self.frac_prec[1]))

If we need to localize numbers without rounding, we can't use these methods.

The minimal default decimal precision per method are:

  • babel.numbers.format_decimal() => 3 digits after the dot
  • babel.numbers.format_currency() => 2 digits after the dot

Proof:

>>> import babel
>>> set([babel.Locale.parse(l).decimal_formats._data[None].frac_prec
...      for l in babel.localedata.locale_identifiers()])
set([(0, 6), (0, 3)])
>>>
>>> import babel
>>> set([babel.Locale.parse(l).currency_formats._data[None].frac_prec
...      for l in babel.localedata.locale_identifiers()])
set([(2, 2)])
>>>

So if you have monetary amounts to localize, and they're already rounded to 2 trailing digits, then you're lucky. Using any of the format_*() methods will have no side effects.

But for other numbers with higher precision, using format_*() as-is is dangerous. It will introduce unwanted rounding. For example, calling format_currency(0.9999, 'EUR', locale='fr') will return 1,00 €. I expect here to get the pristine 0,9999 € string.

I think there must be a clean and documented way to bypass arbitrary rounding when localizing numbers.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions