Skip to main content

dashu_float/math/
mod.rs

1//! Advanced mathematical functions
2
3use crate::{
4    error::{panic_infinite, panic_nan, panic_overflow, panic_underflow},
5    fbig::FBig,
6    repr::{Context, Repr, Word},
7    round::{Round, Rounded},
8};
9
10pub mod consts;
11pub mod trig;
12
13/// The result of an advanced mathematical operation.
14///
15/// This enum is used to handle non-finite results (NaN, Infinite) and
16/// boundary conditions (Overflow, Underflow) without panicking,
17/// as the core [`FBig`] type only represents finite numbers.
18///
19/// Finite results are wrapped in a [Rounded] to preserve rounding information.
20#[derive(Clone, Debug, PartialEq, Eq)]
21pub enum FpResult<const B: Word> {
22    Normal(Rounded<Repr<B>>),
23    Overflow,
24    Underflow,
25    NaN,
26    /// An exact infinite result is obtained from finite inputs, such as
27    /// divide by zero or logarithm of zero.
28    Infinite,
29}
30
31impl<const B: Word> FpResult<B> {
32    /// Convert the result into an [`FBig`] with the given context.
33    ///
34    /// # Panics
35    /// Panics if the result is not `Normal`.
36    #[inline]
37    #[must_use]
38    pub fn value<R: Round>(self, context: &Context<R>) -> FBig<R, B> {
39        match self {
40            Self::Normal(rounded) => FBig::new(rounded.value(), *context),
41            Self::NaN => panic_nan(),
42            Self::Infinite => panic_infinite(),
43            Self::Overflow => panic_overflow(),
44            Self::Underflow => panic_underflow(),
45        }
46    }
47
48    /// Convert the result into an optional [`FBig`] with the given context.
49    /// Returns `None` if the result is not `Normal`.
50    #[inline]
51    #[must_use]
52    pub fn ok<R: Round>(self, context: &Context<R>) -> Option<Rounded<FBig<R, B>>> {
53        match self {
54            Self::Normal(rounded) => Some(rounded.map(|repr| FBig::new(repr, *context))),
55            _ => None,
56        }
57    }
58
59    /// Returns `true` if the result is `NaN`.
60    #[inline]
61    #[must_use]
62    pub const fn is_nan(&self) -> bool {
63        matches!(self, Self::NaN)
64    }
65
66    /// Returns `true` if the result is `Infinite`.
67    #[inline]
68    #[must_use]
69    pub const fn is_infinite(&self) -> bool {
70        matches!(self, Self::Infinite)
71    }
72
73    /// Returns `true` if the result is a normal finite value.
74    #[inline]
75    #[must_use]
76    pub const fn is_normal(&self) -> bool {
77        matches!(self, Self::Normal(_))
78    }
79
80    /// Returns `true` if the result is a finite value (Normal, Overflow, or Underflow).
81    #[inline]
82    #[must_use]
83    pub const fn is_finite(&self) -> bool {
84        matches!(self, Self::Normal(_) | Self::Overflow | Self::Underflow)
85    }
86}