Skip to main content

dashu_float/
lib.rs

1// Copyright (c) 2022 Jacob Zhong
2//
3// Licensed under either of
4//
5// * Apache License, Version 2.0
6//   (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
7// * MIT license
8//   (LICENSE-MIT or https://opensource.org/licenses/MIT)
9//
10// at your option.
11//
12// Unless you explicitly state otherwise, any contribution intentionally submitted
13// for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
14// dual licensed as above, without any additional terms or conditions.
15
16//! A big float library supporting arbitrary precision, arbitrary base and arbitrary rounding mode.
17//!
18//! The library implements efficient large floating point arithmetic in pure Rust.
19//!
20//! The main type is [FBig] representing the arbitrary precision floating point numbers, the [DBig] type
21//! is an alias supporting decimal floating point numbers.
22//!
23//! To construct big floats from literals, please use the [`dashu-macro`](https://docs.rs/dashu-macros/latest/dashu_macros/)
24//! crate for your convenience.
25//!
26//! # Examples
27//!
28//! ```
29//! # use dashu_base::ParseError;
30//! use core::str::FromStr;
31//! use core::convert::TryFrom;
32//! use dashu_float::DBig;
33//!
34//! // due to the limit of rust generics, the default float type
35//! // need to be instantiate explicitly
36//! type FBig = dashu_float::FBig;
37//!
38//! let a = FBig::try_from(-12.34_f32).unwrap();
39//! let b = DBig::from_str("6.022e23")?;
40//! let c = DBig::from_parts(271828.into(), -5);
41//! let d: DBig = "-0.0123456789".parse()?;
42//! let e = 2 * b.ln() + DBig::ONE;
43//! let f = &c * d.powi(10.into()) / 7;
44//!
45//! assert_eq!(a.precision(), 24); // IEEE 754 single has 24 significant bits
46//! assert_eq!(b.precision(), 4); // 4 decimal digits
47//!
48//! assert!(b > c); // comparison is limited in the same base
49//! assert!(a.to_decimal().value() < d);
50//! assert_eq!(c.to_string(), "2.71828");
51//!
52//! // use associated functions of the context to get full result
53//! use dashu_base::Approximation::*;
54//! use dashu_float::{Context, round::{mode::HalfAway, Rounding::*}};
55//! let ctxt = Context::<HalfAway>::new(6);
56//! assert_eq!(ctxt.exp(DBig::ONE.repr(), None), Ok(Inexact(c, NoOp)));
57//! # Ok::<(), ParseError>(())
58//! ```
59//!
60//! # Optional dependencies
61//!
62//! * `std` (*default*): enable `std` for dependencies.
63
64#![cfg_attr(not(feature = "std"), no_std)]
65#![deny(missing_docs)]
66#![deny(clippy::dbg_macro)]
67#![deny(clippy::undocumented_unsafe_blocks)]
68#![deny(clippy::let_underscore_must_use)]
69
70extern crate alloc;
71// The rkyv derive macros emit `rkyv::` paths; alias the renamed optional dep back so they resolve.
72#[cfg(feature = "rkyv_v07")]
73extern crate rkyv_v07 as rkyv;
74
75mod add;
76mod ball;
77mod cmp;
78mod convert;
79mod div;
80mod error;
81mod exp;
82mod fbig;
83mod fbig_cached;
84mod fbig_cached_ops;
85mod fmt;
86mod helper_macros;
87mod iter;
88mod log;
89mod mag;
90pub mod math;
91mod mul;
92pub mod ops;
93mod parse;
94mod repr;
95mod repr_ops;
96mod root;
97pub mod round;
98mod round_ops;
99mod shift;
100mod sign;
101mod third_party;
102mod utils;
103mod ziv;
104
105// Retry-count profiling for the Ziv loops (available with the `tuning` feature).
106#[cfg(any(all(test, feature = "std"), feature = "tuning"))]
107pub use ziv::{ziv_retries, ziv_retries_reset};
108// The per-attempt radius trace hook is deliberately `#[doc(hidden)]`: usable by profiling
109// harnesses, but not a stable API promise.
110#[cfg(any(all(test, feature = "std"), feature = "tuning"))]
111#[doc(hidden)]
112pub use ziv::{ziv_set_trace_hook, ZivTraceFn};
113
114// The error-propagation substrate (`Ball` over a `Mag` radius), shared in lockstep with
115// `dashu-cmplx`: its `CBall` composes complex balls on top of these real ones. Deliberately
116// `#[doc(hidden)]` — excluded from the semver and stability guarantees, consumed only by the
117// crates of this repository, which are released together.
118#[doc(hidden)]
119pub use ball::{ulp_mag, Ball};
120#[doc(hidden)]
121pub use mag::Mag;
122
123// All the public items from third_party will be exposed
124#[allow(unused_imports)]
125pub use third_party::*;
126
127pub use fbig::FBig;
128pub use fbig_cached::CachedFBig;
129pub use math::cache::ConstCache;
130pub use repr::{Context, Repr};
131pub use {crate::error::FpError, crate::math::FpResult};
132
133/// Multi-precision float number with decimal exponent and [HalfAway][round::mode::HalfAway] rounding mode
134pub type DBig = FBig<round::mode::HalfAway, 10>;
135
136#[doc(hidden)]
137pub use dashu_int::Word; // for macros
138
139// Infinities are now first-class *terminal* values: operations produce them as results
140// (1/0 → +inf, ln(0) → -inf, …) but reject infinite *inputs* (FpError::InfiniteInput / panic),
141// which structurally avoids the NaN-producing indeterminate forms (inf−inf, inf/inf, 0·inf).
142// IEEE signed zero is supported (`-0`), so 1/-0 = -inf is well-defined.