static int mprimef(unsigned int *n, unsigned int *q, int k) { int i, j; unsigned int *t, *x, *y; // generate x t = mcopy(n); while (1) { for (i = 0; i < MLENGTH(t); i++) t[i] = rand(); x = mmod(t, n); if (!MZERO(x) && !MEQUAL(x, 1)) break; mfree(x); } mfree(t); // exponentiate y = mmodpow(x, q, n); // done? if (MEQUAL(y, 1)) { mfree(x); mfree(y); return 1; } j = 0; while (1) { // y = n - 1? t = msub(n, y); if (MEQUAL(t, 1)) { mfree(t); mfree(x); mfree(y); return 1; } mfree(t); if (++j == k) { mfree(x); mfree(y); return 0; } // y = (y ^ 2) mod n t = mmul(y, y); mfree(y); y = mmod(t, n); mfree(t); // y = 1? if (MEQUAL(y, 1)) { mfree(x); mfree(y); return 0; } } }
void yybesselj(void) { double d; int n; N = pop(); X = pop(); push(N); n = pop_integer(); // numerical result if (isdouble(X) && n != (int) 0x80000000) { //d = jn(n, X->u.d); push_double(d); return; } // bessej(0,0) = 1 if (iszero(X) && iszero(N)) { push_integer(1); return; } // besselj(0,n) = 0 if (iszero(X) && n != (int) 0x80000000) { push_integer(0); return; } // half arguments if (N->k == NUM && MEQUAL(N->u.q.b, 2)) { // n = 1/2 if (MEQUAL(N->u.q.a, 1)) { push_integer(2); push_symbol(PI); divide(); push(X); divide(); push_rational(1, 2); power(); push(X); sine(); multiply(); return; } // n = -1/2 if (MEQUAL(N->u.q.a, -1)) { push_integer(2); push_symbol(PI); divide(); push(X); divide(); push_rational(1, 2); power(); push(X); cosine(); multiply(); return; } // besselj(x,n) = (2/x) (n-sgn(n)) besselj(x,n-sgn(n)) - besselj(x,n-2*sgn(n)) push_integer(MSIGN(N->u.q.a)); SGN = pop(); push_integer(2); push(X); divide(); push(N); push(SGN); subtract(); multiply(); push(X); push(N); push(SGN); subtract(); besselj(); multiply(); push(X); push(N); push_integer(2); push(SGN); multiply(); subtract(); besselj(); subtract(); return; } push(symbol(BESSELJ)); push(X); push(N); list(3); }