Skip to content

Commit f12e975

Browse files
committed
Add a documentation section about number rounding
Explain how the user can control the behaviour of number rounding when formatting numeric values or currencies.
1 parent 8341064 commit f12e975

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

docs/numbers.rst

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,58 @@ the specification. The following table is just a relatively brief overview.
8686
+----------+-----------------------------------------------------------------+
8787

8888

89+
Rounding Modes
90+
==============
91+
92+
Since Babel makes full use of Python's `Decimal`_ type to perform number
93+
rounding before formatting, users have the chance to control the rounding mode
94+
and other configurable parameters through the active `Context`_ instance.
95+
96+
By default, Python rounding mode is ``ROUND_HALF_EVEN`` which complies with
97+
`UTS #35 section 3.3`_. Yet, the caller has the opportunity to tweak the
98+
current context before formatting a number or currency:
99+
100+
.. code-block:: pycon
101+
102+
>>> from babel.numbers import decimal, format_decimal
103+
>>> with decimal.localcontext(decimal.Context(rounding=decimal.ROUND_DOWN)):
104+
>>> txt = format_decimal(123.99, format='#', locale='en_US')
105+
>>> txt
106+
u'123'
107+
108+
It is also possible to use ``decimal.setcontext`` or directly modifying the
109+
instance returned by ``decimal.getcontext``. However, using a context manager
110+
is always more convenient due to the automatic restoration and the ability to
111+
nest them.
112+
113+
Whatever mechanism is chosen, always make use of the ``decimal`` module imported
114+
from ``babel.numbers``. For efficiency reasons, Babel uses the fastest decimal
115+
implementation available, such as `cdecimal`_. These various implementation
116+
offer an identical API, but their types and instances do **not** interoperate
117+
with each other.
118+
119+
For example, the previous example can be slightly modified to generate
120+
unexpected results on Python 2.7, with the `cdecimal`_ module installed:
121+
122+
.. code-block:: pycon
123+
124+
>>> from decimal import localcontext, Context, ROUND_DOWN
125+
>>> from babel.numbers import format_decimal
126+
>>> with localcontext(Context(rounding=ROUND_DOWN)):
127+
>>> txt = format_decimal(123.99, format='#', locale='en_US')
128+
>>> txt
129+
u'124'
130+
131+
Changing other parameters such as the precision may also alter the results of
132+
the number formatting functions. Remember to test your code to make sure it
133+
behaves as desired.
134+
135+
.. _Decimal: https://docs.python.org/3/library/decimal.html#decimal-objects
136+
.. _Context: https://docs.python.org/3/library/decimal.html#context-objects
137+
.. _`UTS #35 section 3.3`: http://www.unicode.org/reports/tr35/tr35-numbers.html#Formatting
138+
.. _cdecimal: https://pypi.python.org/pypi/cdecimal
139+
140+
89141
Parsing Numbers
90142
===============
91143

0 commit comments

Comments
 (0)