static F2(jtcfrz){A z;B b=0,p;I j,n;Z c,d,*t,*u,*v; RZ(w=rsort(w)); n=AN(w); u=ZAV(w); GATV(z,CMPX,1+n,1,0); v=ZAV(z); *v=c=*ZAV(a); p=!c.im; for(j=0;j<n;++j){ d=znegate(u[j]); t=j+v; *(1+t)=*t; DO(j, *t=zplus(*(t-1),ztymes(d,*t)); --t;); *v=ztymes(d,*v); if(p&&d.im)if(b=!b)c=u[j]; else if(p=ZCJ(c,u[j])){t=v; DO(2+j, t++->im=0.0;);}
void Montgomery_multiplication(long b, long n, verylong zm, verylong zx, verylong zy, verylong *zA) { long i, n1 = n + 1, u, mp, *a, *m, *x, *y; verylong za = 0, zb = 0, zc = 0, zd = 0, zs = 0; a = calloc(n1, sizeof(long)); m = calloc(n1, sizeof(long)); x = calloc(n1, sizeof(long)); y = calloc(n1, sizeof(long)); if (a == 0 || m == 0 || x == 0 || y == 0) { printf("*error*\ncan't get memory from Montgomery"); printf(" multiplication"); exit(1); } zintoz(b, &zb); zinvmod(zm, zb, &za); znegate(&za); mp = zsmod(za, b); radix_representation(b, n1, m, zm); radix_representation(b, n1, x, zx); radix_representation(b, n1, y, zy); zzero(zA); for (i = 0; i < n; i++) { radix_representation(b, n1, a, *zA); u = ((a[0] + x[i] * y[0]) * mp) % b; zsmul(zy, x[i], &za); zsmul(zm, u, &zc); zadd(*zA, za, &zs); zadd(zs, zc, &zd); zsdiv(zd, b, zA); } if (zcompare(*zA, zm) >= 0) { zsub(*zA, zm, &za); zcopy(za, zA); } free(a); free(m); free(x); free(y); zfree(&za); zfree(&zb); zfree(&zc); zfree(&zd); zfree(&zs); }
int simultaneous_diophantine(double delta, long n, verylong zQ, verylong *zP, verylong *zp, verylong *zq) { double P, Q, l; int equal, found; long i, j, n1 = n + 1; verylong zd = 0, zl = 0, zr = 0, zs = 0, zt = 0; verylong **zA = allocate_very_matrix(1, n1, 1, n1); verylong **zh = allocate_very_matrix(1, n1, 1, n1); Q = zdoub(zQ); zintoz(pow(Q, delta), &zl); l = 1.0 / zdoub(zl); zmul(zl, zQ, &zd); for (i = 1; i <= n; i++) zcopy(zd, &zA[i][i]); znegate(&zl); for (i = 1; i <= n; i++) zmul(zl, zq[i], &zA[n1][i]); zone(&zA[n1][n1]); int_LLL(n1, zA, zh); found = 0; for (j = 1; !found && j <= n1; j++) { zcopy(zA[j][n1], zP); if (zcompare(*zP, zQ) != 0) { for (i = 1; i <= n; i++) { zdiv(zA[j][i], zl, &zr, &zs); zmul(*zP, zq[i], &zt); zadd(zr, zt, &zs); zdiv(zs, zQ, &zp[i], &zr); } P = zdoub(*zP); #ifdef DEBUG if (n <= 16) { printf("p = "); zwrite(*zP); printf(" p[i] "); for (i = 1; i <= n; i++) { zwrite(zp[i]); printf(" "); } printf("\n"); } #endif if (zcompare(*zP, 0) != 0) { equal = 1; for (i = 1; equal && i <= n; i++) equal = fabs(P * zdoub(zq[i]) / Q - zdoub(zp[i])) <= l; } else equal = 0; found = equal; } } free_very_matrix(zA, 1, n1, 1, n1); free_very_matrix(zh, 1, n1, 1, n1); zfree(&zd); zfree(&zl); zfree(&zr); zfree(&zs); zfree(&zt); return found; }