fast_posit/
lib.rs

1#![cfg_attr(not(test), no_std)]
2//! This crate provides a correct, clean, flexible, and 🚀 *fast* software implementation of
3//! [Posit arithmetic](https://posithub.org/docs/posit_standard-2.pdf).
4//!
5//! # Introduction
6//!
7//! Posits are an alternative floating point format proposed by John Gustafson in 2017, with the
8//! first published standard in 2022. They have several interesting features that make them an
9//! excellent replacement for traditional IEEE754 floats, in domains such as neural networks or
10//! HPC.
11//!
12//! The following references are useful if you are not yet familiar with posits:
13//!
14//!   - [Posit standard](https://posithub.org/docs/posit_standard-2.pdf) (2022)
15//!   - [Original extended paper](https://posithub.org/docs/Posits4.pdf) (2017)
16//!   - [Book](https://doi.org/10.1201/9781003466024 ) (2024)
17//!
18//! This crate aims to implement the entire posit standard and beyond, including features such as
19//! arbitrary posit and quire sizes beyond those prescribed by the standard. Versions prior to
20//! 1.0.0, however, may be incomplete. Correctness is ensured via extensive testing against an
21//! oracle.
22//!
23//! # Usage
24//!
25//! ```
26//! // Use standard posit types, or define your own.
27//! # use fast_posit::Posit;
28//! use fast_posit::{p8, p16, p32, p64};  // Standard: n bits, 2 exponent bits
29//! type MyPosit = Posit<24, 3, i32>;  // Non-standard: 24 bits, 3 exponent bits
30//!
31//! // Create posits from ints, IEEE floats, strings, constants, or a raw bit representation.
32//! # use fast_posit::{RoundFrom, RoundInto};
33//! let a = p32::round_from(2.71_f64);
34//! let b = p32::round_from(42_i32);
35//! let c = p32::from_bits(0x7f001337);
36//! let d = p32::MIN_POSITIVE;
37//!
38//! // Perform basic arithmetic and comparisons with the usual operators.
39//! assert!(p16::round_from(2.14_f32) + p16::ONE == 3.14_f32.round_into());
40//! assert!(p16::MIN_POSITIVE < 1e-15_f32.round_into());
41//! // # use core::f32
42//! // assert!(p16::from  p16::round_from(f32::consts::PI));
43//!
44//! // Convert posits back to ints, IEEE floats, strings, or a raw bit representation.
45//! assert_eq!(p8::ONE.to_bits(), 0b01000000)
46//! ```
47//!
48//! # Performance
49//!
50//! In terms of performance, you can expect as a *very rough estimate* 50 to 80 Mops/s
51//! (corresponding to about a 10–20× slowdown relative to native hw FPU operations) on an 11th gen
52//! Intel x86 core at 2.80GHz. This is, as far as we're aware, faster (or at least as fast) as any
53//! freely available software implementation of posit arithmetic.
54//!
55//! Needless to say, both absolute performance and relative performance vs the FPU varies depending
56//! on your system.
57//!
58//! This crate includes benchmarks; run them with `cargo bench -F bench`.
59
60mod posit;
61mod underlying;
62
63pub use posit::Posit;
64pub use underlying::Int;
65
66/// Standard-defined 8-bit posit (with 2-bit exponent).
67#[allow(non_camel_case_types)]
68pub type p8 = Posit<8, 2, i8>;
69
70/// Standard-defined 16-bit posit (with 2-bit exponent).
71#[allow(non_camel_case_types)]
72pub type p16 = Posit<16, 2, i16>;
73
74/// Standard-defined 32-bit posit (with 2-bit exponent).
75#[allow(non_camel_case_types)]
76pub type p32 = Posit<32, 2, i32>;
77
78/// Standard-defined 64-bit posit (with 2-bit exponent).
79#[allow(non_camel_case_types)]
80pub type p64 = Posit<64, 2, i64>;
81
82pub use posit::convert::{RoundFrom, RoundInto};
83
84/// Re-export some internals for benchmarking purposes, only on `feature = "bench"`.
85#[cfg(feature = "bench")]
86mod bench;