#define FFTP3_BACKWARD CLEVER
#ifdef DEBUG_FFTP3_OPERATIONS
-#define check_fftp3_word(x) if ((x.w1 >= p1) || (x.w2 >= p2) || (x.w3 >= p3)) cl_abort()
+#define check_fftp3_word(x) if ((x.w1 >= p1) || (x.w2 >= p2) || (x.w3 >= p3)) throw runtime_exception()
#else
#define check_fftp3_word(x)
#endif
mulp3(ma,mb, or);
mulp3(a,b, r);
if (!((r.w1 == or.w1) && (r.w2 == or.w2) && (r.w3 == or.w3)))
- cl_abort();
+ throw runtime_exception();
}
#define mulp3 mulp3_doublecheck
#endif /* DEBUG_FFTP3_OPERATIONS */
var fftp3_word w_N;
mulp3(w[N-1],fftp3_roots_of_1[n], w_N);
if (!(w_N.w1 == 1 && w_N.w2 == 1 && w_N.w3 == 1))
- cl_abort();
+ throw runtime_exception();
w_N = w[N>>1];
if (!(w_N.w1 == p1-1 && w_N.w2 == p2-1 && w_N.w3 == p3-1))
- cl_abort();
+ throw runtime_exception();
}
#endif
var bool squaring = (x == y);
// Es ist 2 <= len1 <= len2.
{
// Methode:
- // source1 ist ein Stück der Länge N1, source2 ein oder mehrere Stücke
- // der Länge N2, mit N1+N2 <= N, wobei N Zweierpotenz ist.
+ // source1 ist ein Stück der Länge N1, source2 ein oder mehrere Stücke
+ // der Länge N2, mit N1+N2 <= N, wobei N Zweierpotenz ist.
// sum(i=0..N-1, x_i b^i) * sum(i=0..N-1, y_i b^i) wird errechnet,
// indem man die beiden Polynome
// sum(i=0..N-1, x_i T^i), sum(i=0..N-1, y_i T^i)
var uint32 n;
integerlengthC(len1-1, n=); // 2^(n-1) < len1 <= 2^n
var uintC len = (uintC)1 << n; // kleinste Zweierpotenz >= len1
- // Wählt man N = len, so hat man ceiling(len2/(len-len1+1)) * FFT(len).
- // Wählt man N = 2*len, so hat man ceiling(len2/(2*len-len1+1)) * FFT(2*len).
- // Wir wählen das billigere von beiden:
+ // Wählt man N = len, so hat man ceiling(len2/(len-len1+1)) * FFT(len).
+ // Wählt man N = 2*len, so hat man ceiling(len2/(2*len-len1+1)) * FFT(2*len).
+ // Wir wählen das billigere von beiden:
// Bei ceiling(len2/(len-len1+1)) <= 2 * ceiling(len2/(2*len-len1+1))
// nimmt man N = len, bei ....... > ........ dagegen N = 2*len.
- // (Wahl von N = 4*len oder mehr bringt nur in Extremfällen etwas.)
+ // (Wahl von N = 4*len oder mehr bringt nur in Extremfällen etwas.)
if (len2 > 2 * (len-len1+1) * (len2 <= (2*len-len1+1) ? 1 : ceiling(len2,(2*len-len1+1)))) {
n = n+1;
len = len << 1;
mulu_loop_lsp(lspref(sourceptr2,0),sourceptr1,tmpptr,len1);
if (addto_loop_lsp(tmpptr,destptr,len1+1))
if (inc_loop_lsp(destptr lspop (len1+1),destlen-(len1+1)))
- cl_abort();
+ throw runtime_exception();
} else {
var uintC destlenp = len1 + len2p - 1;
// destlenp = min(N,destlen-1).
combinep3(z[i],arrayLSDptr(z_i,3));
#ifdef DEBUG_FFTP3
if (!(arrayLSref(z_i,3,2) < N))
- cl_abort();
+ throw runtime_exception();
#endif
// Add z[i] to the accumulator.
tmp = arrayLSref(z_i,3,0);
// ac2 = 0.
if (ac1 > 0) {
if (!((i += 2) <= destlen))
- cl_abort();
+ throw runtime_exception();
tmp = lspref(ptr,0);
if ((ac0 += tmp) < tmp)
++ac1;
lsshrink(ptr);
if (ac1 < tmp)
if (inc_loop_lsp(ptr,destlen-i))
- cl_abort();
+ throw runtime_exception();
} else if (ac0 > 0) {
if (!((i += 1) <= destlen))
- cl_abort();
+ throw runtime_exception();
tmp = lspref(ptr,0);
ac0 += tmp;
lspref(ptr,0) = ac0;
lsshrink(ptr);
if (ac0 < tmp)
if (inc_loop_lsp(ptr,destlen-i))
- cl_abort();
+ throw runtime_exception();
}
}
#ifdef DEBUG_FFTP3
// If destlenp < N, check that the remaining z[i] are 0.
for (i = destlenp; i < N; i++)
if (z[i].w1 > 0 || z[i].w2 > 0 || z[i].w3 > 0)
- cl_abort();
+ throw runtime_exception();
#endif
}
// Decrement len2.