flexfloat/
lib.rs

1//! # FlexFloat
2//!
3//! A high-precision library for arbitrary precision floating-point arithmetic with growable exponents
4//! and fixed-size fractions. FlexFloat extends IEEE 754 double-precision format to handle numbers
5//! beyond the standard range while maintaining computational efficiency and precision consistency.
6//!
7//! ## Overview
8//!
9//! FlexFloat provides:
10//! - **Growable exponents**: Automatically expand exponent bit width when needed
11//! - **Fixed-size fractions**: Maintain consistent precision (52-bit mantissa by default)
12//! - **IEEE 754 compatibility**: Full support for standard floating-point operations
13//! - **Arbitrary precision**: Handle numbers far beyond standard double-precision range
14//! - **Efficient operations**: Optimized for performance while maintaining precision
15//!
16//! ## Architecture
17//!
18//! The library is built around two main components:
19//!
20//! ### BitArray Module
21//! Provides flexible bit manipulation and storage with support for various backing implementations:
22//! - Boolean vector-based storage for simplicity and debugging
23//! - Extensible to other bit storage formats
24//! - Conversion utilities for common numeric types
25//!
26//! ### FlexFloat Module
27//! Implements the core floating-point type with:
28//! - Sign bit (1 bit)
29//! - Variable-width exponent (starts at 11 bits, grows as needed)
30//! - Fixed-width fraction (52 bits for IEEE 754 compatibility)
31//!
32//! ## Quick Start
33//!
34//! ```rust
35//! use flexfloat::FlexFloat;
36//!
37//! // Create from standard f64
38//! let x = FlexFloat::from(3.14159);
39//! let y = FlexFloat::from(2.71828);
40//!
41//! // Perform arithmetic operations
42//! let neg_x = -x;
43//! let abs_y = y.abs();
44//!
45//! // Convert back to f64 (when in range)
46//! let result: f64 = neg_x.into();
47//! ```
48//!
49//! ## Special Values
50//!
51//! FlexFloat supports all IEEE 754 special values:
52//!
53//! ```rust
54//! use flexfloat::FlexFloat;
55//!
56//! let zero = FlexFloat::zero();
57//! let pos_inf = FlexFloat::pos_infinity();
58//! let neg_inf = FlexFloat::neg_infinity();
59//! let nan = FlexFloat::nan();
60//!
61//! assert!(zero.is_zero());
62//! assert!(pos_inf.is_infinity());
63//! assert!(nan.is_nan());
64//! ```
65
66pub mod bitarray;
67pub mod flexfloat;
68
69// Re-export the main types for convenience
70pub use bitarray::{BitArray, BoolBitArray, DefaultBitArray};
71pub use flexfloat::FlexFloat;
72
73pub mod prelude {
74    //! Prelude module for FlexFloat.
75    //!
76    //! This module re-exports commonly used types and traits from the FlexFloat crate,
77    //! allowing for easier imports in user code.
78
79    pub use crate::bitarray::*;
80    pub use crate::flexfloat::FlexFloat;
81}
82
83#[cfg(test)]
84mod tests {
85    use std::sync::OnceLock;
86
87    use rand::{Rng, SeedableRng, rngs::StdRng};
88    use rstest::fixture;
89
90    static SEED: OnceLock<u64> = OnceLock::new();
91
92    #[fixture]
93    pub const fn n_experiments() -> usize {
94        100_000
95    }
96
97    #[fixture]
98    pub fn seed() -> u64 {
99        *SEED.get_or_init(|| rand::rng().random())
100    }
101
102    #[fixture]
103    pub fn rng(n_experiments: usize, seed: u64) -> impl Rng {
104        println!("{} experiments with seed {}", n_experiments, seed);
105        StdRng::seed_from_u64(seed)
106    }
107}