[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
??