#include "longlong.h"
#include "fmpq.h"
int
_fmpq_cmp(const fmpz_t p, const fmpz_t q, const fmpz_t r, const fmpz_t s)
{
int s1, s2, res;
flint_bitcnt_t bp, bq, br, bs;
fmpz_t t, u;
if (!COEFF_IS_MPZ(*p) && !COEFF_IS_MPZ(*q) && !COEFF_IS_MPZ(*r) && !COEFF_IS_MPZ(*s))
{
ulong a1, a0, b1, b0;
smul_ppmm(a1, a0, *p, *s);
smul_ppmm(b1, b0, *q, *r);
sub_ddmmss(a1, a0, a1, a0, b1, b0);
if ((slong) a1 < 0)
return -1;
if ((slong) a1 > 0)
return 1;
return a0 != 0;
}
if (fmpz_equal(q, s))
return fmpz_cmp(p, r);
s1 = fmpz_sgn(p);
s2 = fmpz_sgn(r);
if (s1 != s2)
return s1 < s2 ? -1 : 1;
bp = fmpz_bits(p);
bq = fmpz_bits(q);
br = fmpz_bits(r);
bs = fmpz_bits(s);
if (bp + bs + 1 < br + bq)
return -s1;
if (bp + bs > br + bq + 1)
return s1;
if (fmpz_is_one(q))
{
fmpz_init(t);
fmpz_mul(t, p, s);
res = fmpz_cmp(t, r);
fmpz_clear(t);
}
else if (fmpz_is_one(s))
{
fmpz_init(u);
fmpz_mul(u, q, r);
res = fmpz_cmp(p, u);
fmpz_clear(u);
}
else
{
fmpz_init(t);
fmpz_init(u);
fmpz_mul(t, p, s);
fmpz_mul(u, q, r);
res = fmpz_cmp(t, u);
fmpz_clear(t);
fmpz_clear(u);
}
return res;
}
int
fmpq_cmp(const fmpq_t x, const fmpq_t y)
{
return _fmpq_cmp(fmpq_numref(x), fmpq_denref(x),
fmpq_numref(y), fmpq_denref(y));
}
int _fmpq_cmp_fmpz(const fmpz_t p, const fmpz_t q, const fmpz_t r)
{
fmpz one = 1;
return _fmpq_cmp(p, q, r, &one);
}
int fmpq_cmp_fmpz(const fmpq_t x, const fmpz_t y)
{
return _fmpq_cmp_fmpz(fmpq_numref(x), fmpq_denref(x), y);
}
int
_fmpq_cmp_si(const fmpz_t p, const fmpz_t q, slong c)
{
int s1, s2, res;
flint_bitcnt_t bp, bq, bc;
fmpz_t u;
if (fmpz_is_one(q))
return fmpz_cmp_si(p, c);
if (!COEFF_IS_MPZ(*p) && !COEFF_IS_MPZ(*q))
{
ulong a1, a0, b1, b0;
a0 = *p;
a1 = FLINT_SIGN_EXT(a0);
smul_ppmm(b1, b0, *q, c);
sub_ddmmss(a1, a0, a1, a0, b1, b0);
if ((slong) a1 < 0)
return -1;
if ((slong) a1 > 0)
return 1;
return a0 != 0;
}
s1 = fmpz_sgn(p);
s2 = FLINT_SGN(c);
if (s1 != s2)
return s1 < s2 ? -1 : 1;
if (s1 == 0)
return 0;
bp = fmpz_bits(p);
bq = fmpz_bits(q);
bc = FLINT_BIT_COUNT(FLINT_UABS(c));
if (bp + 2 < bc + bq)
return -s1;
if (bp > bc + bq)
return s1;
fmpz_init(u);
fmpz_mul_si(u, q, c);
res = fmpz_cmp(p, u);
fmpz_clear(u);
return res;
}
int
fmpq_cmp_si(const fmpq_t x, slong c)
{
return _fmpq_cmp_si(fmpq_numref(x), fmpq_denref(x), c);
}
int
_fmpq_cmp_ui(const fmpz_t p, const fmpz_t q, ulong c)
{
int s1, s2, res;
flint_bitcnt_t bp, bq, bc;
fmpz_t u;
if (fmpz_is_one(q))
return fmpz_cmp_ui(p, c);
if (!COEFF_IS_MPZ(*p) && !COEFF_IS_MPZ(*q) && c <= WORD_MAX)
{
ulong a1, a0, b1, b0;
a0 = *p;
a1 = FLINT_SIGN_EXT(a0);
smul_ppmm(b1, b0, *q, c);
sub_ddmmss(a1, a0, a1, a0, b1, b0);
if ((slong) a1 < 0)
return -1;
if ((slong) a1 > 0)
return 1;
return a0 != 0;
}
s1 = fmpz_sgn(p);
s2 = (c > 0);
if (s1 != s2)
return s1 < s2 ? -1 : 1;
bp = fmpz_bits(p);
bq = fmpz_bits(q);
bc = FLINT_BIT_COUNT(c);
if (bp + 2 < bc + bq)
return -s1;
if (bp > bc + bq)
return s1;
fmpz_init(u);
fmpz_mul_ui(u, q, c);
res = fmpz_cmp(p, u);
fmpz_clear(u);
return res;
}
int
fmpq_cmp_ui(const fmpq_t x, ulong c)
{
return _fmpq_cmp_ui(fmpq_numref(x), fmpq_denref(x), c);
}