]> git.ipfire.org Git - thirdparty/babel.git/commitdiff
Add a documentation section about number rounding 410/head
authorIsaac Jurado <diptongo@gmail.com>
Sun, 29 May 2016 08:26:07 +0000 (10:26 +0200)
committerIsaac Jurado <diptongo@gmail.com>
Sun, 29 May 2016 08:26:07 +0000 (10:26 +0200)
Explain how the user can control the behaviour of number rounding when
formatting numeric values or currencies.

docs/numbers.rst

index fbba1f3ed27c6160e18c7c970ec70c4bbe35512b..1443b7cf5dc5c17f0b2fb31aef300454a21d0d2c 100644 (file)
@@ -86,6 +86,58 @@ the specification. The following table is just a relatively brief overview.
   +----------+-----------------------------------------------------------------+
 
 
+Rounding Modes
+==============
+
+Since Babel makes full use of Python's `Decimal`_ type to perform number
+rounding before formatting, users have the chance to control the rounding mode
+and other configurable parameters through the active `Context`_ instance.
+
+By default, Python rounding mode is ``ROUND_HALF_EVEN`` which complies with
+`UTS #35 section 3.3`_.  Yet, the caller has the opportunity to tweak the
+current context before formatting a number or currency:
+
+.. code-block:: pycon
+
+    >>> from babel.numbers import decimal, format_decimal
+    >>> with decimal.localcontext(decimal.Context(rounding=decimal.ROUND_DOWN)):
+    >>>    txt = format_decimal(123.99, format='#', locale='en_US')
+    >>> txt
+    u'123'
+
+It is also possible to use ``decimal.setcontext`` or directly modifying the
+instance returned by ``decimal.getcontext``.  However, using a context manager
+is always more convenient due to the automatic restoration and the ability to
+nest them.
+
+Whatever mechanism is chosen, always make use of the ``decimal`` module imported
+from ``babel.numbers``.  For efficiency reasons, Babel uses the fastest decimal
+implementation available, such as `cdecimal`_.  These various implementation
+offer an identical API, but their types and instances do **not** interoperate
+with each other.
+
+For example, the previous example can be slightly modified to generate
+unexpected results on Python 2.7, with the `cdecimal`_ module installed:
+
+.. code-block:: pycon
+
+    >>> from decimal import localcontext, Context, ROUND_DOWN
+    >>> from babel.numbers import format_decimal
+    >>> with localcontext(Context(rounding=ROUND_DOWN)):
+    >>>    txt = format_decimal(123.99, format='#', locale='en_US')
+    >>> txt
+    u'124'
+
+Changing other parameters such as the precision may also alter the results of
+the number formatting functions.  Remember to test your code to make sure it
+behaves as desired.
+
+.. _Decimal: https://docs.python.org/3/library/decimal.html#decimal-objects
+.. _Context: https://docs.python.org/3/library/decimal.html#context-objects
+.. _`UTS #35 section 3.3`: http://www.unicode.org/reports/tr35/tr35-numbers.html#Formatting
+.. _cdecimal: https://pypi.python.org/pypi/cdecimal
+
+
 Parsing Numbers
 ===============