two_sum

Function two_sum 

Source
fn two_sum(a: f64, b: f64) -> (f64, f64)
Examples found in repository?
crates/competitive/src/num/quad_double.rs (line 64)
63fn three_three_sum(a: f64, b: f64, c: f64) -> (f64, f64, f64) {
64    let (u, v) = two_sum(a, b);
65    let (r0, w) = two_sum(u, c);
66    let (r1, r2) = two_sum(v, w);
67    (r0, r1, r2)
68}
69
70fn three_two_sum(a: f64, b: f64, c: f64) -> (f64, f64) {
71    let (u, v) = two_sum(a, b);
72    let (r0, w) = two_sum(u, c);
73    let r1 = v + w;
74    (r0, r1)
75}
76
77fn multiple_three_sum(xs: &[f64]) -> (f64, f64, f64) {
78    let (mut r0, mut r1, mut r2) = (*xs.first().unwrap_or(&0.), 0., 0.);
79    for &x in xs.iter() {
80        let (s, e) = two_sum(r0, x);
81        r0 = s;
82        let (s, e) = two_sum(r1, e);
83        r1 = s;
84        r2 += e;
85    }
86    (r0, r1, r2)
87}
88
89fn multiple_two_sum(xs: &[f64]) -> (f64, f64) {
90    let (mut r0, mut r1) = (*xs.first().unwrap_or(&0.), 0.);
91    for &x in xs.iter() {
92        let (s, e) = two_sum(r0, x);
93        r0 = s;
94        r1 += e;
95    }
96    (r0, r1)
97}
98
99impl Add<f64> for QuadDouble {
100    type Output = Self;
101    fn add(self, rhs: f64) -> Self::Output {
102        let (t0, e) = two_sum(self.0, rhs);
103        let (t1, e) = two_sum(self.1, e);
104        let (t2, e) = two_sum(self.2, e);
105        let (t3, t4) = two_sum(self.3, e);
106        Self::renormalize(t0, t1, t2, t3, t4)
107    }
108}
109
110fn double_accumulate(u: f64, v: f64, x: f64) -> (f64, f64, f64) {
111    let (s, mut v) = two_sum(v, x);
112    let (mut s, mut u) = two_sum(u, s);
113    if u == 0. {
114        u = s;
115        s = 0.;
116    }
117    if v == 0. {
118        v = u;
119        u = s;
120        s = 0.
121    }
122    (s, u, v)
123}
124
125impl Add<QuadDouble> for QuadDouble {
126    type Output = Self;
127    fn add(self, rhs: Self) -> Self::Output {
128        let mut x = [0.; 8];
129        let (mut i, mut j, mut k) = (0, 0, 0);
130        while k < 8 {
131            if j >= 4 || i < 4 && self[i].abs() > rhs[j].abs() {
132                x[k] = self[i];
133                i += 1;
134            } else {
135                x[k] = rhs[j];
136                j += 1;
137            }
138            k += 1;
139        }
140
141        let (mut u, mut v) = (0., 0.);
142        let (mut k, mut i) = (0, 0);
143        let mut c = [0.; 4];
144        while k < 4 && i < 8 {
145            let tpl = double_accumulate(u, v, x[i]);
146            let s = tpl.0;
147            u = tpl.1;
148            v = tpl.2;
149            if s != 0. {
150                c[k] = s;
151                k += 1;
152            }
153            i += 1;
154        }
155        if k < 2 {
156            c[k + 1] = v;
157        }
158        if k < 3 {
159            c[k] = u;
160        }
161        Self::renormalize(c[0], c[1], c[2], c[3], 0.)
162    }
163}
164
165impl Sub for QuadDouble {
166    type Output = Self;
167    fn sub(self, rhs: Self) -> Self::Output {
168        self + -rhs
169    }
170}
171
172impl Neg for QuadDouble {
173    type Output = Self;
174    fn neg(self) -> Self::Output {
175        Self(-self.0, -self.1, -self.2, -self.3)
176    }
177}
178
179impl Mul<f64> for QuadDouble {
180    type Output = Self;
181    fn mul(self, rhs: f64) -> Self::Output {
182        let (t0, e0) = two_prod(self.0, rhs);
183        let (p1, e1) = two_prod(self.1, rhs);
184        let (p2, e2) = two_prod(self.2, rhs);
185        let p3 = self.3 * rhs;
186
187        let (t1, e4) = two_sum(p1, e0);
188        let (t2, e5, e6) = three_three_sum(p2, e1, e4);
189        let (t3, e7) = three_two_sum(p3, e2, e5);
190        let t4 = e7 + e6;
191        Self::renormalize(t0, t1, t2, t3, t4)
192    }