for (i = 0; i < n; i++) {
p = qhat*vn[i];
t = un[i+j] - k - (p & 0xFFFFFFFFLL);
- un[i+j] = t;
+ un[i+j] = (t & 0xffffffffLL);
k = (p >> 32) - (t >> 32);
}
-#else
+#endif
+#ifdef EXPERIMENT1
for (i = 0; i < n; i++) {
unsigned rhi;
unsigned long long sum;
k = rhi;
un[i+j] = sum & 0xffffffff;
}
+#endif
+#define EXPERIMENT2
+#ifdef EXPERIMENT2
+ unsigned long phi[200]; // yes, not malloced, we know
+ unsigned long plo[200]; // yes, not malloced, we know
+ // double-width multiply with strange subtract only on bottom half
+ for (i = 0; i < n; i++) {
+ unsigned long long p = qhat*vn[i];
+ plo[i] = un[i+j] - (p&0xffffffffLL);
+ phi[i] = p >> 32;
+ }
+ for (i = 0; i < n; i++) {
+ t = plo[i] - k; // subtract previous carry
+ un[i+j] = (t & 0xffffffffLL);
+ k = phi[i] - (t >> 32); // take top-halves for new carry
+ }
#endif
t = un[j+n] - k;
un[j+n] = t;