PiEngine is a high-performance Pi calculator capable of computing billions of digits with extreme precision. It features dual implementations in OCaml and C, serving as a benchmark for high-precision arithmetic and functional vs. systems programming paradigms.
We have successfully reached the 1 Billion Digits milestone! By leveraging the Chudnovsky algorithm and binary splitting, PiEngine efficiently handles massive numbers. Note that computing 1B digits and beyond is primarily dependent on available RAM, as the intermediate values in the binary splitting process grow significantly.
- Dual Implementations (Branch-separated):
- OCaml (
mainbranch): Utilizing the powerful Zarith library for clean, high-performance functional code. - C (
v3-Cbranch): Leveraging GMP and MPFR for maximum low-level efficiency.
- OCaml (
- Binary Splitting: Optimized series summation that reduces the complexity of large multiplications.
- High Performance: Designed to scale from thousands to billions of digits.
- Cross-Platform: Tested on Linux and macOS.
- Robust CLI: Complete control over precision, output, and verbose timing metrics.
PiEngine uses the world-record Chudnovsky algorithm, which converges at approximately 14 digits per term:
To compute this series efficiently, we use Binary Splitting. Instead of computing each term and adding it to a running total, we recursively split the series into two halves. This allows us to use large, efficient multiplications (Karatsuba or FFT-based) provided by GMP and Zarith, significantly speeding up the process for millions of digits. For very large digit counts, the memory usage becomes the primary bottleneck.
Our next target is the 10 Billion Digits milestone. To reach this level of performance and handle the increasing computational load, future updates will focus on:
- Parallelization: Implementing multi-threaded binary splitting to utilize all available CPU cores.
- Memory Optimization: Reducing the memory footprint during the division and square root phases.
- Disk-based Computation: Exploring swapping strategies for digit counts that exceed available RAM.
- OPAM
- Dune
- zarith library
opam install zarith dune- GMP
- MPFR
# Ubuntu/Debian
sudo apt install libgmp-dev libmpfr-dev
# Arch Linux
sudo pacman -S gmp mpfrThe OCaml version offers a balance of safety and performance.
dune build
dune exec bin/main.exe -- --digits 1000000 --verbose --output pi.txtThe C version provides low-level control and direct access to GMP primitives.
git checkout v3-C
make
./piengine --digits 1000000 --verbose --output pi.txtBoth versions support identical CLI flags:
- -d, --digits NUM: Number of digits to compute (default: 1000).
- -o, --output FILE: Write the result to a file instead of stdout.
- -v, --verbose: Display detailed timing and performance information.
- -h, --help: Show help message.
The project is organized into two primary branches:
main: Contains the OCaml implementation.bin/: CLI application.lib/: Core Chudnovsky logic.test/: Regression and comparison tests.
v3-C: Contains the C implementation.src/: Core logic and CLI.tests/: Unit tests.
| Milestone | Digits | Status |
|---|---|---|
| Milestone 1 | 1,000 | Complete |
| Milestone 2 | 1,000,000 | Complete |
| Milestone 3 | 100,000,000 | Complete |
| Milestone 4 | 1,000,000,000 | Achieved |
| Milestone 5 | 10,000,000,000 | In Progress / Planned |
We ensure correctness by comparing results between the OCaml and C implementations, as well as against known reference constants.
# Run OCaml tests (on main branch)
./test_pi.sh“Mathematics is the music of reason.”