#![forbid(unsafe_code)]
#![allow(clippy::approx_constant)]
#![allow(clippy::excessive_precision)]
#![allow(clippy::float_cmp)]
#![allow(clippy::suspicious_arithmetic_impl)]
#![allow(clippy::suspicious_op_assign_impl)]
use core::fmt;
use std::error;
#[cfg(not(all(windows, target_env = "gnu")))]
mod math {
#[inline(always)]
pub fn fma(a: f64, b: f64, c: f64) -> f64 {
a.mul_add(b, c)
}
}
#[cfg(all(windows, target_env = "gnu"))]
mod math {
#[inline(always)]
pub fn fma(a: f64, b: f64, c: f64) -> f64 {
libm::fma(a, b, c)
}
}
#[macro_use]
mod ops_util;
#[cfg(test)]
#[macro_use]
mod test_util;
mod arithmetic;
mod base;
pub mod consts;
mod convert;
mod format;
mod functions;
mod num_integration;
pub use base::no_overlap;
#[cfg(feature = "serde")]
mod serde_helper {
use super::{TwoFloat, TwoFloatError};
#[derive(serde::Deserialize)]
#[serde(rename = "TwoFloat")]
pub(super) struct TwoFloatDeserializeHelper {
hi: f64,
lo: f64,
}
impl core::convert::TryFrom<TwoFloatDeserializeHelper> for TwoFloat {
type Error = TwoFloatError;
fn try_from(value: TwoFloatDeserializeHelper) -> Result<Self, Self::Error> {
TwoFloat::try_from((value.hi, value.lo))
}
}
}
#[derive(Debug, Default, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "serde",
serde(try_from = "serde_helper::TwoFloatDeserializeHelper")
)]
pub struct TwoFloat {
pub(crate) hi: f64,
pub(crate) lo: f64,
}
#[non_exhaustive]
#[derive(Debug)]
pub enum TwoFloatError {
ConversionError,
ParseError,
}
impl fmt::Display for TwoFloatError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::ConversionError => f.pad("invalid TwoFloat conversion"),
Self::ParseError => f.pad("parsing not supported"),
}
}
}
impl error::Error for TwoFloatError {}