#include "gmpcompat.h"
#include "mpn_extras.h"
#include "fmpz.h"
static int flint_mpn_cmp2abs(nn_srcptr x, slong xn, nn_srcptr a, slong an)
{
ulong xhi, ahi;
FLINT_ASSERT(an >= 0);
FLINT_ASSERT(xn >= 0);
FLINT_ASSERT(xn == 0 || x[xn - 1] != 0);
FLINT_ASSERT(an == 0 || a[an - 1] != 0);
if (an > xn)
return -1;
if (an + 1 < xn)
return 1;
xhi = an == xn ? 0 : x[an];
ahi = 0;
while (an > 0)
{
ahi = MPN_LEFT_SHIFT_HI(ahi, a[an - 1], 1);
if (xhi != ahi)
return xhi > ahi ? 1 : -1;
ahi = a[an - 1];
xhi = x[an - 1];
an--;
}
ahi = MPN_LEFT_SHIFT_HI(ahi, UWORD(0), 1);
if (xhi != ahi)
return xhi > ahi ? 1 : -1;
return 0;
}
int fmpz_cmp2abs(const fmpz_t a, const fmpz_t b)
{
if (!COEFF_IS_MPZ(*b))
{
ulong ub = FLINT_ABS(*b);
if (!COEFF_IS_MPZ(*a))
{
ulong ua = FLINT_ABS(*a);
return ua < 2*ub ? -1 : ua > 2*ub ? 1 : 0;
}
else
{
return flint_mpn_cmp2abs(COEFF_TO_PTR(*a)->_mp_d,
FLINT_ABS(COEFF_TO_PTR(*a)->_mp_size),
&ub, ub != 0);
}
}
else
{
if (!COEFF_IS_MPZ(*a))
{
return -1;
}
else
{
return flint_mpn_cmp2abs(COEFF_TO_PTR(*a)->_mp_d,
FLINT_ABS(COEFF_TO_PTR(*a)->_mp_size),
COEFF_TO_PTR(*b)->_mp_d,
FLINT_ABS(COEFF_TO_PTR(*b)->_mp_size));
}
}
}
int fmpz_cmpabs(const fmpz_t f, const fmpz_t g)
{
if (f == g) return 0;
if (!COEFF_IS_MPZ(*f))
{
if (!COEFF_IS_MPZ(*g))
{
ulong uf = FLINT_ABS(*f);
ulong ug = FLINT_ABS(*g);
return (uf < ug ? -1 : (uf > ug));
}
else return -1;
}
else
{
if (!COEFF_IS_MPZ(*g)) return 1;
else return mpz_cmpabs(COEFF_TO_PTR(*f), COEFF_TO_PTR(*g));
}
}
int
fmpz_cmp(const fmpz_t f, const fmpz_t g)
{
int sign;
if (f == g)
return 0;
if (!COEFF_IS_MPZ(*f))
{
if (!COEFF_IS_MPZ(*g))
{
return (*f < *g ? -1 : *f > *g);
}
else
{
sign = mpz_sgn(COEFF_TO_PTR(*g));
return (*f >= 0 && sign < 0) ? 1 : -sign;
}
}
else
{
if (!COEFF_IS_MPZ(*g))
{
sign = mpz_sgn(COEFF_TO_PTR(*f));
return (*g >= 0 && sign < 0) ? -1 : sign;
}
else
return mpz_cmp(COEFF_TO_PTR(*f), COEFF_TO_PTR(*g));
}
}
int
fmpz_cmp_si(const fmpz_t f, slong g)
{
fmpz c = *f;
if (!COEFF_IS_MPZ(c))
return c < g ? -1 : c > g;
else
return flint_mpz_cmp_si(COEFF_TO_PTR(c), g);
}
int
fmpz_cmp_ui(const fmpz_t f, ulong g)
{
fmpz c = *f;
if (!COEFF_IS_MPZ(c))
{
if (c < WORD(0) || g > COEFF_MAX)
return -1;
else
return c < (slong) g ? -1 : c > (slong) g;
}
else
return flint_mpz_cmp_ui(COEFF_TO_PTR(c), g);
}