- static int highest_result = 0;
- // algorithm not applicable to B(0), so just store it
- if (results.size()==0)
- results.push_back(cln::cl_RA(1));
-
- int n = nn.to_long();
- for (int i=highest_result; i<n/2; ++i) {
- cln::cl_RA B = 0;
- long n = 8;
- long m = 5;
- long d1 = i;
- long d2 = 2*i-1;
- for (int j=i; j>0; --j) {
- B = cln::cl_I(n*m) * (B+results[j]) / (d1*d2);
- n += 4;
- m += 2;
- d1 -= 1;
- d2 -= 2;
- }
- B = (1 - ((B+1)/(2*i+3))) / (cln::cl_I(1)<<(2*i+2));
- results.push_back(B);
- ++highest_result;
+ static unsigned next_r = 0;
+
+ // algorithm not applicable to B(2), so just store it
+ if (!next_r) {
+ results.push_back(cln::recip(cln::cl_RA(6)));
+ next_r = 4;
+ }
+ if (n<next_r)
+ return results[n/2-1];
+
+ results.reserve(n/2);
+ for (unsigned p=next_r; p<=n; p+=2) {
+ cln::cl_I c = 1; // seed for binonmial coefficients
+ cln::cl_RA b = cln::cl_RA(1-p)/2;
+ const unsigned p3 = p+3;
+ const unsigned pm = p-2;
+ unsigned i, k, p_2;
+ // test if intermediate unsigned int can be represented by immediate
+ // objects by CLN (i.e. < 2^29 for 32 Bit machines, see <cln/object.h>)
+ if (p < (1UL<<cl_value_len/2)) {
+ for (i=2, k=1, p_2=p/2; i<=pm; i+=2, ++k, --p_2) {
+ c = cln::exquo(c * ((p3-i) * p_2), (i-1)*k);
+ b = b + c*results[k-1];
+ }
+ } else {
+ for (i=2, k=1, p_2=p/2; i<=pm; i+=2, ++k, --p_2) {
+ c = cln::exquo((c * (p3-i)) * p_2, cln::cl_I(i-1)*k);
+ b = b + c*results[k-1];
+ }
+ }
+ results.push_back(-b/(p+1));