[Python-Dev] Revised decimal type PEP

Michael McLay mclay@nist.gov
Mon, 30 Jul 2001 11:06:52 -0400


PEP: 2XX
Title: Adding a Decimal type to Python
Version: $Revision:$
Author: mclay@nist.gov <mclay@nist.gov>
Status: Draft
Type: ??
Created: 25-Jul-2001
Python-Version: 2.2


Introduction

    This PEP describes the addition of a decimal number type to Python.


Rationale

    The original Python numerical model included int, float, and long.
    By popular request the imaginary type was added to improve support
    for engineering and scientific applications.  The addition of a
    decimal number type to Python will improve support for business
    applications as well as improve the utility of Python a teaching
    language. 

    The number types currently used in Python are encoded as base two
    binary numbers.  The base 2 arithmetic used by binary numbers closely
    approximates the decimal number system and for many applications the
    differences in the calculations are unimportant.  The decimal number
    type encodes numbers as decimal digits and use base 10 arithmetic.
    This is the number system taught to the general public and it is the
    system used by businesses when making financial calculations.

    For financial and accounting applications the difference between
    binary and decimal types is significant. Consequently the computer
    languages used for business application development, such as COBOL,
    use decimal types.  

    The decimal number type meets the expectations of non-computer
    scientists when making calculations.  For these users the rounding
    errors that occur when using binary numbers is a source of confusion
    and irritation.


Implementation

    The tokenizer will be modified to recognized number literals with
    a 'd' suffix and a decimal() function will be added to __builtins__.  
    A decimal number can be used to represent integers and floating point
    numbers and decimal numbers can also be displayed using scientific
    notation. Examples of decimal numbers include:  

        1234d
        -1234d
        1234.56d
        -1234.56d
        1234.56e2d
        -1234.56e-2d

    The type returned by either a decimal floating point or a decimal
    integer is the same: 

    >>> type(12.2d)
    <type 'decimal'>
    >>> type(12d)
    <type 'decimal'>
    >>> type(-12d+12d)
    <type 'decimal'>
    >>> type(12d+12.0d)
    <type 'decimal'>

    This proposal will also add an optional  'b' suffix to the
    representation of binary float type literals and binary int type
    literals. 

    >>> float(12b)
    12.0
    >>> type(12.2b)
    <type 'float'>
    >>> type(float(12b))
    <type 'float'>
    >>> type(12b)
    <type 'int'>

    The decimal() conversion function added to __builtins__ will support
    conversions of strings, and binary types to decimal.

    >>> type(decimal("12d"))
    <type 'decimal'>
    >>> type(decimal("12"))
    <type 'decimal'>
    >>> type(decimal(12b))
    <type 'decimal'>
    >>> type(decimal(12.0b))
    <type 'decimal'>
    >>> type(decimal(123456789123L))
    <type 'decimal'>

    The conversion functions int() and float() in the __builtin__ module
    will support conversion of decimal numbers to the binary number
    types. 

    >>> type(int(12d))
    <type 'int'>
    >>> type(float(12.0d))
    <type 'float'>

    Expressions that mix integers with decimals will automatically convert
    the integer to decimal and the result will be a decimal number.

    >>> type(12d + 4b)
    <type 'decimal'>
    >>> type(12b + 4d)
    <type 'decimal'>
    >>> type(12d + len('abc'))
    <type 'decimal'>
    >>> 3d/4b
    0.75

    Expressions that mix binary floats with decimals introduce the
    possibility of unexpected results because the two number types use
    different internal representations for the same numerical value.  The
    severity of this problem is dependent on the application domain.  For
    applications that normally use binary numbers the error may not be
    important and the conversion should be done silently.  For newbie
    programmers a warning should be issued so the newbie will be able to
    locate the source of a discrepancy between the expected results and
    the results that were achieved.  For financial applications the mixing
    of floating point with binary numbers should raise an exception.

    To accommodate the three possible usage models the python interpreter
    command line options will be used to set the level for warning and 
    error messages. The three levels are:   

    promiscuous mode,	-f or  --promiscuous
    safe mode 		-s or --save
    pedantic mode	-p or --pedantic

    The default setting will be set to the safe setting. In safe mode
    mixing decimal and binary floats in a calculation will trigger a warning
    message. 

    >>> type(12.3d + 12.2b)
    Warning: the calculation mixes decimal numbers with binary floats
    <type 'decimal'>

    In promiscuous mode warnings will be turned off.

    >>> type(12.3d + 12.2b)
    <type 'decimal'>

    In pedantic mode warning from safe mode will be turned into exceptions.

    >>> type(12.3d + 12.2b)
    Traceback (innermost last):
      File "<stdin>", line 1, in ?
    TypeError: the calculation mixes decimal numbers with binary floats


Semantics of Decimal Numbers

    ??