From 04565f36dffcbfaae83d83768c162a9c05c3060b Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Mon, 24 May 2021 18:02:51 -0700 Subject: [PATCH] start adding FloatFloat --- src/algorithms.rs | 1 + src/algorithms/float_float.rs | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/algorithms/float_float.rs diff --git a/src/algorithms.rs b/src/algorithms.rs index 4c2aa82..b2c7a20 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -1,4 +1,5 @@ pub mod base; +pub mod float_float; pub mod ilogb; pub mod integer; pub mod roots; diff --git a/src/algorithms/float_float.rs b/src/algorithms/float_float.rs new file mode 100644 index 0000000..8676f1d --- /dev/null +++ b/src/algorithms/float_float.rs @@ -0,0 +1,58 @@ +//! based on algorithms from: +//! +//! Mioara Joldes, Jean-Michel Muller, and Valentina Popescu. 2017. Tight and Rigorous Error Bounds for Basic +//! Building Blocks of Double-Word Arithmetic. ACM Trans. Math. Softw. 44, 2, Article 15res (October 2017), +//! 27 pages. +//! +//! https://doi.org/10.1145/3121432 + +use crate::traits::{Context, ConvertTo, Float}; + +/// a higher-precision float represented as the exact sum of two floats `F` +#[derive(Copy, Clone, Debug)] +pub struct FloatFloat { + high: F, + low: F, +} + +impl FloatFloat { + pub fn new(high: F, low: F) -> Self { + Self { high, low } + } + pub fn from_float(high: F) -> Self { + Self { + high, + low: high.ctx().make(0.to()), + } + } + pub fn to_float(self) -> F { + self.high + self.low + } + /// create a `FloatFloat` from a sum of two floats, where `big.abs() >= small.abs()` + /// + /// based on Algorithm #1 from Joldes et al. (2017) + pub fn from_ordered_sum(big: F, small: F) -> Self { + let high = big + small; + let low = small - (high - big); + Self { high, low } + } + /// create a `FloatFloat` from a sum of two floats + /// + /// based on Algorithm #2 from Joldes et al. (2017) + pub fn from_sum(a: F, b: F) -> Self { + let high = a + b; + let a_prime = high - b; + let b_prime = high - a; + let low = (a - a_prime) + (b - b_prime); + Self { high, low } + } + /// create a `FloatFloat` from a sum of two floats + /// + /// based on Algorithm #3 from Joldes et al. (2017) + #[cfg(feature = "fma")] + pub fn from_product(a: F, b: F) -> Self { + let high = a * b; + let low = a.fma(b, -high); + Self { high, low } + } +} -- 2.30.2