Table of Contents

libmpdec quick start

This section contains the bare minimum required to get started. Refer to the libmpdec manual for anything more advanced.

libmpdec build

For a custom build, refer to INSTALL.txt. For a Windows build, see vcbuild\README.txt.

# Unix:
make check # downloads test cases, no executable code.

libmpdec example program

# Unix:
cd libmpdec
make examples

# Try a couple of values:
./pow 2 1234567
4.9963964863286026867472463500015498863E+371641  Inexact Rounded

libmpdec++ quick start

This section contains the bare minimum required to get started. Refer to the libmpdec++ manual for anything more advanced.

libmpdec++ build

libmpdec++ is built by default, unless –disable-cxx is passed to ./configure. For a Windows build, see vcbuild\README.txt.

# Unix:
make check # downloads test cases, no executable code.

libmpdec++ example program

Build the examples:

# Unix:
cd libmpdec++
make examples

# Try a couple of values:
./pi 7

./pi 40

./factorial 5

./factorial 40

time ./factorial 1000000 > /dev/null
real    0m2.204s

Write Python in C++

Compare the pi function to the Python version further down. There is not much difference:

pi(int prec)
    context.prec(prec + 2);

    Decimal lasts = 0;
    Decimal t = 3;
    Decimal s = 3;
    Decimal n = 1;
    Decimal na = 0;
    Decimal d = 0;
    Decimal da = 24;

    while (s != lasts) {
        lasts = s;
        n += na;
        na += 8;
        d += da;
        da += 32;
        t = (t * n) / d;
        s += t;

    return +s;

cdecimal quick start


Unix, Mac OS X

As for every C extension, the build requires a working C compiler. For most Linux distributions, the Python header files have to be installed explicitly, since they are shipped as a separate package:

# Debian, Ubuntu:
sudo apt-get install gcc make
sudo apt-get install python-dev

# Fedora, RedHat:
sudo yum install gcc make
sudo yum install python-devel

# openSUSE:
sudo zypper install gcc make
sudo zypper install python-devel

# BSD:
# You know what to do.

# Mac OS X:
# Install Xcode and Python headers.

If pip is present on the system, installation should be as easy as:

pip install cdecimal


tar xvzf cdecimal-2.3.tar.gz
cd cdecimal-2.3
python install

If problems arise, read the file PYINSTALL.txt which comes with the distribution.


The easiest way is to use the binary installers. Otherwise, the build requires Visual Studio.

Factorial in pure Python

Showing off cdecimal’s bignum speed. Note that the factorial function is entirely written in Python and does not call a C factorial function.

from cdecimal import *

def _factorial(n, m):
    if (n > m):
        return _factorial(m, n)
    elif m == 0:
        return 1
    elif n == m:
        return n
        return _factorial(n, (n+m)//2) * _factorial((n+m)//2 + 1, m)

def factorial(n):
    return _factorial(n, 0)

c = getcontext()
c.prec = MAX_PREC

# 1000000! in pure Python
x = factorial(Decimal(1000000))
sx = str(x)

# Compare to Python integers:
y = factorial(1000000)
sy = str(y)

Calculating pi in pure Python

Showing off cdecimal’s speed for small precisions. Again, the algorithm is in pure Python and does not involve calling a custom C pi-function. This is also the benchmark where cdecimal is often faster than Java’s BigDecimal.

import cdecimal
import decimal

def pi(module, prec):
    """From the documentation"""
    module.getcontext().prec = prec + 2
    D = module.Decimal
    lasts, t, s, n, na, d, da = D(0), D(3), D(3), D(1), D(0), D(0), D(24)
    while s != lasts:
        lasts = s
        n, na = n+na, na+8
        d, da = d+da, da+32
        t = (t * n) / d
        s += t
    module.getcontext().prec -= 2
    return +s

for i in range(10000):
    x = pi(cdecimal, 28)

for i in range(10000):
    y = pi(decimal, 28)

Telco benchmark

The telco benchmark was devised by Mike Cowlishaw as a way of measuring decimal performance in a real world telecom application.

Get, telco.testb, and unzip

python         # sanity check
python full    # benchmark

# Edit and change decimal to cdecimal.
# Speedups should be about 30x.
python         # sanity check
python full    # benchmark

Use cdecimal globally

This is a nice tip from the sqlalchemy developers. Since cdecimal.Decimal currently does not support mixed operations with decimal.Decimal, the easiest way to enforce global use of cdecimal is to occupy both places for cdecimal and decimal in sys.modules. This must take place at program start, before importing anything else.

This technique is used in the following section in the file

# At program start:
import sys
import cdecimal
sys.modules["decimal"] = cdecimal

# Further imports:
import psycopg2       # psycopg2 imports cdecimal, masquerading as decimal
from decimal import * # same here, this is now cdecimal


The PostgreSQL database adapter psycopg supports PostgreSQL’s numeric type. For a speed comparison, download setup_dectest.sql and Naturally, both PostgreSQL and psycopg2 are required for this benchmark.

The benchmark inserts 100000 rows containing numeric data into the test database. Subsequently, it fetches all rows. Since INSERT has a lot of database overhead, the main speed gains are in FETCHALL. Similar speed gains (10x) have also been reported by Informix database users.

# Setup a test database:
psql < setup_dectest.sql

# Run the benchmark for

# Edit and uncomment the top two import lines to
# use cdecimal globally.
# The speedup should be about 1.7x for INSERT and 12x for FETCHALL.