apfp - Adaptive Precision Floating-Point
Robust geometric predicates using adaptive precision arithmetic. The library provides exact sign computation for arithmetic expressions, automatically escalating precision only when needed.
Features
- Robust geometric predicates:
orient2d,incircle,cmp_distthat handle near-degenerate cases correctly - General-purpose sign computation: The
apfp_signum!macro computes exact signs for arbitrary arithmetic expressions - Adaptive staging: Fast f64 evaluation with error bounds, falling back to double-double or exact arithmetic only when necessary
- Allocation-free: All operations use fixed stack buffers computed at compile time
Quick Start
[]
= "0.1"
Using Pre-built Predicates
use ;
use Ordering;
let a = new;
let b = new;
let c = new;
// Orientation test: is c left of, right of, or on line ab?
match orient2d
// Distance comparison: is p closer to origin than q?
let origin = new;
let p = new;
let q = new;
match cmp_dist
Building Custom Expressions
Use apfp_signum! to compute the exact sign of any arithmetic expression:
use ;
// Compute sign of a determinant
let a = 1.0_f64;
let b = 2.0_f64;
let c = 3.0_f64;
let d = 4.0_f64;
let sign = apfp_signum!;
assert_eq!; // 1*4 - 2*3 = -2 < 0
// Use square() for squared terms (more efficient than x * x)
let x = 3.0_f64;
let y = 4.0_f64;
let z = 5.0_f64;
let sign = apfp_signum!;
assert_eq!; // 9 + 16 - 25 = 0
The macro supports +, -, *, and square() operations on f64 values.
How It Works
The library implements Shewchuk's adaptive precision arithmetic:
- Fast path: Evaluate in f64 and compute an error bound. If the result magnitude exceeds the bound, return immediately.
- Double-double path: Re-evaluate using double-double arithmetic (~106 bits). Check against tighter bounds.
- Exact path: Compute the exact result using floating-point expansions.
Most calls complete in the fast path. The adaptive approach provides both correctness and performance.
Performance
On random inputs, orient2d performs within 1.1x of the geometry-predicates crate (which uses the same underlying algorithm). The macro-based approach allows the compiler to inline and optimize the entire computation.
Requirements
- IEEE 754 binary floating-point with round-to-nearest-even
- Rust 2024 edition
License
This project is released under The Unlicense.