5.16 FixedPoint -- Fixed decimal object with settable precision and user definable rounding

The fixedpoint module defines the FixedPoint class which provides a fixed decimal data type that supports python operators and standard functions. FixedPoint objects are useful when computing financial transactions where precision is critical.

class FixedPoint([value=0[, precision=DEFAULT_PRECISION]])
A Fixedpoint instance is a fixed decimal data type with support for the standard python operators and functions.

FixedPoint objects support decimal arithmetic with a fixed number of digits (called the object's precision) after the decimal point. The number of digits before the decimal point is variable and unbounded.

The precision is user-settable on a per-object basis when a FixedPoint is constructed, and may vary across FixedPoint objects. The precision may also be changed after construction via FixedPoint.set_precision(p). Note that if the precision of a FixedPoint object is reduced via .set_precision, information may be lost to rounding.

The FixedPoint constructor can be passed an int, long, string, float, FixedPoint, or any object convertible to a float via float() or to a long via long(). Passing a precision is optional; if specified, the precision must be a non-negative int. There is no inherent limit on the size of the precision, but if very very large you'll probably run out of memory.

The following Python operators and functions accept FixedPoints in the expected ways:

  + - * / % divmod() with auto-coercion of other types to FixedPoint.
  + - % divmod() of FixedPoints are always exact.
  * / of FixedPoints may lose information to rounding, in which case the result is the infinitely precise answer rounded to the result's precision.
  unary -  
  == != < > <= >= cmp  
  min() max()  
  float() int() long() int and long truncate
  abs()  
  str() repr()  
  hash()  
  use as dict keys  
  use as boolean (e.g. "if some_FixedPoint:" - true iff not zero)
  divmod(x, y) returns (q,r) where q is a long equal to floor(x/y) as if x/y were computed to infinite precision, and r is a FixedPoint equal to x - q * y; no information is lost. Note that q has the sign of y, and abs(r) < abs(y).

When FixedPoint objects of different precision are combined via + - * /, the result is computed to the larger of the inputs' precisions, which also becomes the precision of the resulting FixedPoint object.

 
>>> print FixedPoint("3.42") + FixedPoint("100.005", 3)
103.425
>>>

When a FixedPoint is combined with other numeric types (ints, floats, strings representing a number) via + - * /, then similarly the computation is carried out using- and the result inherits -the FixedPoint's precision.

  
>>> print FixedPoint(1) / 7
0.14
>>> print FixedPoint(1, 30) / 7
0.142857142857142857142857142857
>>>

The string produced by str(x) (implicitly invoked by "print") always contains at least one digit before the decimal point, followed by a decimal point, followed by exactly x.get_precision() digits. If x is negative, str(x)[0] == "-".

Note that conversion of floats to FixedPoint can be surprising, and should be avoided whenever possible. Conversion from string is exact (up to final rounding to the requested precision), so is greatly preferred.

 
>>> print FixedPoint(1.1e30)
1099999999999999993725589651456.00
>>> print FixedPoint("1.1e30")
1100000000000000000000000000000.00
>>>

FixedPoint objects have the following public methods:

copy()
Return a copy of this FixedPoint object.

frac()
Return fractional part of this FixedPoint object. (x.frac() + long(x) == x)

get_precision()
Return the precision of this FixedPoint object. The precision is the number of decimal digits carried after the decimal point, and is an int >= 0.

set_precision([precision=DEFAULT_PRECISION])
Change the precision carried by this FixedPoint to precision. precision must be an int >= 0, and defaults to DEFAULT_PRECISION. If precision is less than this FixedPoint's current precision, information may be lost to rounding.

The fixedpoint module also defines the following (private) functions:

_mkFP(n,p)
Make a FixedPoint object - Return a new FixedPoint with the indicated value n and precision p.

_norm(x,y)
Return xn, yn, p such that:
p = max(x.p, y.p)
x = xn / 10**p
y = yn / 10**p

x must be FixedPoint to begin with; if y is not FixedPoint,it inherits its precision from x.

Note that this method is called a lot, so default-arg tricks are helpful.

_roundquotient(x,y)
Divide x by y, rounding to int via nearest-even. y must be > 0.

_string2exact(s)
Return n, p such that float string value == n * 10**p exactly.

_tento(n[,cache=[]])
Cached computation of 10**n.

_test()
Interface to unit testing framework. Invoked automatically if module run standalone.

The fixedpoint module exports the following data item(s):

DEFAULT_PRECISION
The default FixedPoint precision size, in places to the right of the decimal point. The default is initially set to 2. Usually only interesting at compile time to set the constructor's default precision.


Subsections
See About this document... for information on suggesting changes.