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 }