管理员 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;
}