libmpdec quick start — mpdecimal project (original) (raw)

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

libmpdec/libmpdec++ install

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

Unix:

./configure make

Run the tests (optional). This downloads the official test cases

(text files):

make check

As root, install the libraries:

sudo make install

Depending on your system (e.g., Ubuntu), you may need to run ldconfig.

Replace "/usr/local/lib" with the actual install location that appears

in the "make install" output:

sudo ldconfig /usr/local/lib

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 thelibmpdec++ manual for anything more advanced.

libmpdec++ install

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

libmpdec++ example program

Build the examples:

Unix:

cd libmpdec++ make examples

Try a couple of values:

./pi 7 3.141593

./pi 40 3.141592653589793238462643383279502884197

./factorial 5 120

./factorial 40 815915283247897734345611269596115894272000000000

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:

Decimal 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;
}

context.prec(prec);
return +s;

}

cdecimal quick start

Install

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:

Otherwise:

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

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

Windows

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 else: 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 decimal.py 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.py,telco.testb,expon180-1e6b.zipand unzip expon180-1e6b.zip.

decimal.py

python telco.py # sanity check python telco.py full # benchmark

Edit telco.py and change decimal to cdecimal.

Speedups should be about 30x.

python telco.py # sanity check python telco.py full # benchmark

Use cdecimal globally

This is a nice tip from the sqlalchemydevelopers. 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 filepsycopg.py.

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 ...

PostgreSQL

The PostgreSQL database adapter psycopg supports PostgreSQL’s numeric type. For a speed comparison, downloadsetup_dectest.sql andpsycopg.py. 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 decimal.py:

python psycopg.py

Edit psycopg.py and uncomment the top two import lines to

use cdecimal globally.

The speedup should be about 1.7x for INSERT and 12x for FETCHALL.

python psycopg.py