| 管理员 on Tue, 02 Dec 2025 03:40:24 +0100 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| Add cmpquad function compare two quadratic numbers x and y and used in gcmp |
/* sign(x + s*sqrt(D)) */
static long _signquad1(GEN x, long s, GEN D) {
long sx = gsigne(x);
if (s == sx) return s;
if (!s) return sx;
if (!sx) return s;
return sx*gcmp(gsqr(x),D);
}
/* sign(x + s1*sqrt(D1) + s2*sqrt(D2)) */
static long _signquad2(GEN x, long s1, GEN D1, long s2, GEN D2) {
if (!s2) return _signquad1(x, s1, D1);
if (!s1) return _signquad1(x, s2, D2);
long s = gcmp(D1,D2);
if (!s) return s1 == s2 ? _signquad1(x,s1,gmul2n(D1,2)) : gsigne(x);
if (s < 0) { lswap(s1,s2); swap(D1,D2); }
s = gsigne(x);
if (!s || s == s1) return s1;
return s*_signquad1(gsub(gsub(gsqr(x),D1),D2),-s1*s2,gmul2n(gmul(D1,D2),2));
}
/* assumes typ(x) == t_QUAD && typ(y) == t_QUAD */
long cmpquad(GEN x, GEN y) {
pari_sp av = get_avma();
GEN Tx = gel(x,1), Ty = gel(y,1), a, bx = gel(x,3), by = gel(y,3);
long sbx, sby, s;
if (signe(gel(Tx,2)) > 0 || signe(gel(Ty,2)) > 0)
pari_err_TYPE("quadcmp",x);
sbx = gsigne(bx); sby = gsigne(by);
a = gmul2n(gsub(gel(x,2),gel(y,2)),1);
if (signe(gel(Tx,3))) a = gadd(a,bx);
if (signe(gel(Ty,3))) a = gsub(a,by);
if (sbx) bx = gmul(quad_disc(x),gsqr(bx));
if (sby) by = gmul(quad_disc(y),gsqr(by));
s = _signquad2(a,sbx,bx,-sby,by);
set_avma(av); return s;
}