--- /dev/null
+//! 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<F> {
+ high: F,
+ low: F,
+}
+
+impl<F: Float> FloatFloat<F> {
+ 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 }
+ }
+}