diff --git a/doc/source/fmpz_poly.rst b/doc/source/fmpz_poly.rst
index 20e23f82a1..11321ee9d1 100644
--- a/doc/source/fmpz_poly.rst
+++ b/doc/source/fmpz_poly.rst
@@ -1824,6 +1824,10 @@ Euclidean division
Computes the quotient ``(Q, len-1)`` of ``(A, len)`` upon
division by `x - c`.
+.. function:: void _fmpz_poly_divexact(fmpz * Q, const fmpz * A, slong lenA, const fmpz * B, slong lenB)
+ void fmpz_poly_divexact(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_poly_t B)
+
+ Like :func:`fmpz_poly_div`, but assumes that the division is exact.
Division with precomputed inverse
--------------------------------------------------------------------------------
diff --git a/doc/source/history.rst b/doc/source/history.rst
index 6d51e751ec..b5fa955d42 100644
--- a/doc/source/history.rst
+++ b/doc/source/history.rst
@@ -93,7 +93,7 @@ Jean Kieffer (JK).
currently benefit significantly due to wrapper overheads (some Arb benchmarks
run ~5% faster with this change). (AA, FJ).
* Faster ``_fmpz_vec_dot`` (FJ).
- * Faster basecase ``fmpz_poly`` and ``fmpz_mat`` basecase algorithms
+ * Faster ``fmpz_poly`` and ``fmpz_mat`` basecase algorithms
based on dot products.
* Optimized ``fmpz_mat_mul_classical`` (FJ).
* Added ``fmpz_mat_mul_waksman``, speeding up ``fmpz_mat`` multiplication
diff --git a/src/fmpq_poly/xgcd.c b/src/fmpq_poly/xgcd.c
index 73e3c6bfe4..6f73512abf 100644
--- a/src/fmpq_poly/xgcd.c
+++ b/src/fmpq_poly/xgcd.c
@@ -76,8 +76,8 @@ void _fmpq_poly_xgcd(fmpz *G, fmpz_t denG,
lenD = lenB - lenG + 1;
C = _fmpz_vec_init(lenC + lenD);
D = C + lenC;
- _fmpz_poly_div(C, primA, lenA, G, lenG, 0);
- _fmpz_poly_div(D, primB, lenB, G, lenG, 0);
+ _fmpz_poly_divexact(C, primA, lenA, G, lenG);
+ _fmpz_poly_divexact(D, primB, lenB, G, lenG);
}
else
{
diff --git a/src/fmpz_mpoly_factor/bpoly_factor.c b/src/fmpz_mpoly_factor/bpoly_factor.c
index a874b9e786..942b9c5b68 100644
--- a/src/fmpz_mpoly_factor/bpoly_factor.c
+++ b/src/fmpz_mpoly_factor/bpoly_factor.c
@@ -139,7 +139,7 @@ void fmpz_bpoly_make_primitive(fmpz_poly_t g, fmpz_bpoly_t A)
for (i = 0; i < A->length; i++)
{
- fmpz_poly_div(q, A->coeffs + i, g);
+ fmpz_poly_divexact(q, A->coeffs + i, g);
fmpz_poly_swap(A->coeffs + i, q);
}
diff --git a/src/fmpz_mpoly_factor/lcc_kaltofen.c b/src/fmpz_mpoly_factor/lcc_kaltofen.c
index f2f7af670b..f4202e493a 100644
--- a/src/fmpz_mpoly_factor/lcc_kaltofen.c
+++ b/src/fmpz_mpoly_factor/lcc_kaltofen.c
@@ -151,8 +151,8 @@ static void _make_bases_coprime(
fmpz_poly_gcd(g, A->p + i, B->p + j);
if (fmpz_poly_degree(g) > 0)
{
- fmpz_poly_div(A->p + i, A->p + i, g);
- fmpz_poly_div(B->p + j, B->p + j, g);
+ fmpz_poly_divexact(A->p + i, A->p + i, g);
+ fmpz_poly_divexact(B->p + j, B->p + j, g);
fmpz_poly_factor_fit_length(A, A->num + 1);
fmpz_poly_set(A->p + A->num, g);
A->exp[A->num] = A->exp[i];
diff --git a/src/fmpz_poly.h b/src/fmpz_poly.h
index e6d1319cb6..ec2ad8cf2a 100644
--- a/src/fmpz_poly.h
+++ b/src/fmpz_poly.h
@@ -711,6 +711,9 @@ void _fmpz_poly_divrem_preinv(fmpz * Q, fmpz * A, slong len1,
void fmpz_poly_divrem_preinv(fmpz_poly_t Q, fmpz_poly_t R,
const fmpz_poly_t A, const fmpz_poly_t B, const fmpz_poly_t B_inv);
+void _fmpz_poly_divexact(fmpz * Q, const fmpz * A, slong lenA, const fmpz * B, slong lenB);
+void fmpz_poly_divexact(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_poly_t B);
+
fmpz ** _fmpz_poly_powers_precompute(const fmpz * B, slong len);
void fmpz_poly_powers_precompute(fmpz_poly_powers_precomp_t pinv,
diff --git a/src/fmpz_poly/cos_minpoly.c b/src/fmpz_poly/cos_minpoly.c
index 68bbe2f6b9..754bfe5a36 100644
--- a/src/fmpz_poly/cos_minpoly.c
+++ b/src/fmpz_poly/cos_minpoly.c
@@ -246,7 +246,7 @@ _fmpz_poly_cos_minpoly(fmpz * f, ulong n)
}
}
- _fmpz_poly_div(f, P, Plen, Q, Qlen, 0);
+ _fmpz_poly_divexact(f, P, Plen, Q, Qlen);
_fmpz_vec_clear(P, Pdeg + 1);
_fmpz_vec_clear(Q, Pdeg + 1);
diff --git a/src/fmpz_poly/divexact.c b/src/fmpz_poly/divexact.c
new file mode 100644
index 0000000000..76a57981bf
--- /dev/null
+++ b/src/fmpz_poly/divexact.c
@@ -0,0 +1,108 @@
+/*
+ Copyright (C) 2024 Fredrik Johansson
+
+ This file is part of FLINT.
+
+ FLINT is free software: you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version. See .
+*/
+
+#include "fmpz.h"
+#include "fmpz_vec.h"
+#include "fmpz_poly.h"
+#include "gr.h"
+#include "gr_poly.h"
+
+void
+_fmpz_poly_divexact(fmpz * Q, const fmpz * A, slong lenA,
+ const fmpz * B, slong lenB)
+{
+ slong lenQ = lenA - lenB + 1;
+
+ if (lenQ == 1)
+ {
+ fmpz_divexact(Q, A + lenA - 1, B + lenB - 1);
+ }
+ else if (lenB == 1)
+ {
+ if (fmpz_is_pm1(B))
+ _fmpz_vec_scalar_mul_fmpz(Q, A, lenA, B);
+ else
+ _fmpz_vec_scalar_divexact_fmpz(Q, A, lenA, B);
+ }
+ else if (lenQ <= 100 || lenB <= 16)
+ {
+ gr_ctx_t ctx;
+ gr_ctx_init_fmpz(ctx);
+ GR_MUST_SUCCEED(_gr_poly_divexact_basecase_bidirectional(Q, A, lenA, B, lenB, ctx));
+ }
+ else
+ {
+ /* todo: the true cutoffs are sometimes higher, especially with
+ unbalanced operands, possibly because divconquer division needs tuning */
+ slong A_bits, B_bits, B_cutoff, Q_cutoff;
+ gr_ctx_t ctx;
+ gr_ctx_init_fmpz(ctx);
+
+ A_bits = _fmpz_vec_max_bits(A, lenQ);
+ B_bits = _fmpz_vec_max_bits(B, FLINT_MIN(lenB, lenQ));
+ A_bits = FLINT_ABS(A_bits);
+ B_bits = FLINT_ABS(B_bits);
+
+ B_cutoff = (B_bits > 3000) ? 20 : 60;
+ Q_cutoff = (A_bits > 1000) ? 100 : 200;
+
+ if (A_bits >= 100 * B_bits)
+ {
+ Q_cutoff *= 2;
+ B_cutoff *= 2;
+ }
+
+ if (lenQ <= Q_cutoff || lenB <= B_cutoff)
+ GR_MUST_SUCCEED(_gr_poly_divexact_basecase_bidirectional(Q, A, lenA, B, lenB, ctx));
+ else
+ _fmpz_poly_div(Q, A, lenA, B, lenB, 0);
+ }
+
+}
+
+void
+fmpz_poly_divexact(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_poly_t B)
+{
+ fmpz_poly_t T;
+ slong lenA = A->length;
+ slong lenB = B->length;
+ slong lenQ = lenA - lenB + 1;
+
+ if (lenB == 0)
+ {
+ flint_throw(FLINT_ERROR, "Exception (fmpz_poly_divexact). Division by zero.\n");
+ }
+
+ if (lenA < lenB)
+ {
+ fmpz_poly_zero(Q);
+ return;
+ }
+
+ if (Q == A || Q == B)
+ {
+ fmpz_poly_init2(T, lenQ);
+ _fmpz_poly_divexact(T->coeffs, A->coeffs, lenA, B->coeffs, lenB);
+ _fmpz_poly_set_length(T, lenQ);
+ fmpz_poly_swap(T, Q);
+ fmpz_poly_clear(T);
+ }
+ else
+ {
+ fmpz_poly_fit_length(Q, lenQ);
+ _fmpz_poly_divexact(Q->coeffs, A->coeffs, lenA, B->coeffs, lenB);
+ _fmpz_poly_set_length(Q, lenQ);
+ }
+
+ /* should not be needed, but produce something normalised in case
+ this was called with invalid input */
+ _fmpz_poly_normalise(Q);
+}
diff --git a/src/fmpz_poly/lcm.c b/src/fmpz_poly/lcm.c
index 589110e5da..295f1676ea 100644
--- a/src/fmpz_poly/lcm.c
+++ b/src/fmpz_poly/lcm.c
@@ -39,7 +39,7 @@ void _fmpz_poly_lcm(fmpz * res, const fmpz * poly1, slong len1,
slong lenV = len1 + len2 - lenW;
V = _fmpz_vec_init(lenV);
- _fmpz_poly_div(V, res, len1 + len2 - 1, W, lenW, 0);
+ _fmpz_poly_divexact(V, res, len1 + len2 - 1, W, lenW);
if (fmpz_sgn(V + (lenV - 1)) > 0)
_fmpz_vec_set(res, V, lenV);
else
diff --git a/src/fmpz_poly/remove.c b/src/fmpz_poly/remove.c
index 139bb8172e..afc5a96653 100644
--- a/src/fmpz_poly/remove.c
+++ b/src/fmpz_poly/remove.c
@@ -73,7 +73,7 @@ fmpz_poly_remove(fmpz_poly_t res, const fmpz_poly_t poly1,
while (i > 0 && !fmpz_poly_divides(q, poly1, p))
{
- fmpz_poly_div(p, p, poly2);
+ fmpz_poly_divexact(p, p, poly2);
i--;
}
diff --git a/src/fmpz_poly/test/main.c b/src/fmpz_poly/test/main.c
index 72e62b70ea..67ba9efea1 100644
--- a/src/fmpz_poly/test/main.c
+++ b/src/fmpz_poly/test/main.c
@@ -47,6 +47,7 @@
#include "t-discriminant.c"
#include "t-div_basecase.c"
#include "t-div_divconquer.c"
+#include "t-divexact.c"
#include "t-divhigh_smodp.c"
#include "t-divides.c"
#include "t-divlow_smodp.c"
@@ -224,6 +225,7 @@ test_struct tests[] =
TEST_FUNCTION(fmpz_poly_discriminant),
TEST_FUNCTION(fmpz_poly_div_basecase),
TEST_FUNCTION(fmpz_poly_div_divconquer),
+ TEST_FUNCTION(fmpz_poly_divexact),
TEST_FUNCTION(fmpz_poly_divhigh_smodp),
TEST_FUNCTION(fmpz_poly_divides),
TEST_FUNCTION(fmpz_poly_divlow_smodp),
diff --git a/src/fmpz_poly/test/t-divexact.c b/src/fmpz_poly/test/t-divexact.c
new file mode 100644
index 0000000000..aa84b594c6
--- /dev/null
+++ b/src/fmpz_poly/test/t-divexact.c
@@ -0,0 +1,72 @@
+/*
+ Copyright (C) 2009 William Hart
+ Copyright (C) 2010 Sebastian Pancratz
+
+ This file is part of FLINT.
+
+ FLINT is free software: you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version. See .
+*/
+
+#include "test_helpers.h"
+#include "fmpz.h"
+#include "fmpz_poly.h"
+#include "ulong_extras.h"
+
+TEST_FUNCTION_START(fmpz_poly_divexact, state)
+{
+ int i, result;
+
+ for (i = 0; i < 1000 * flint_test_multiplier(); i++)
+ {
+ fmpz_poly_t a, b, c, q;
+ int aliasing;
+
+ fmpz_poly_init(a);
+ fmpz_poly_init(b);
+ fmpz_poly_init(c);
+ fmpz_poly_init(q);
+
+ fmpz_poly_randtest(a, state, 1 + n_randint(state, 100), 1 + n_randint(state, 200));
+ fmpz_poly_randtest_not_zero(b, state, 1 + n_randint(state, 100), 1 + n_randint(state, 200));
+ fmpz_poly_mul(c, a, b);
+ aliasing = n_randint(state, 3);
+
+ if (aliasing == 0)
+ {
+ fmpz_poly_divexact(q, c, b);
+ }
+ else if (aliasing == 1)
+ {
+ fmpz_poly_set(q, c);
+ fmpz_poly_divexact(q, q, b);
+ }
+ else
+ {
+ fmpz_poly_set(q, b);
+ fmpz_poly_divexact(q, c, q);
+ }
+
+ result = fmpz_poly_equal(q, a);
+
+ if (!result)
+ {
+ flint_printf("FAIL:\n");
+ fmpz_poly_print(a), flint_printf("\n\n");
+ fmpz_poly_print(b), flint_printf("\n\n");
+ fmpz_poly_print(c), flint_printf("\n\n");
+ fmpz_poly_print(q), flint_printf("\n\n");
+ fflush(stdout);
+ flint_abort();
+ }
+
+ fmpz_poly_clear(a);
+ fmpz_poly_clear(b);
+ fmpz_poly_clear(c);
+ fmpz_poly_clear(q);
+ }
+
+ TEST_FUNCTION_END(state);
+}
diff --git a/src/fmpz_poly_factor/factor_squarefree.c b/src/fmpz_poly_factor/factor_squarefree.c
index a9719f20fc..c80fcf0245 100644
--- a/src/fmpz_poly_factor/factor_squarefree.c
+++ b/src/fmpz_poly_factor/factor_squarefree.c
@@ -47,8 +47,8 @@ void fmpz_poly_factor_squarefree(fmpz_poly_factor_t fac, const fmpz_poly_t F)
fmpz_poly_init(w);
fmpz_poly_init(s);
- fmpz_poly_div(v, f, d);
- fmpz_poly_div(w, t1, d);
+ fmpz_poly_divexact(v, f, d);
+ fmpz_poly_divexact(w, t1, d);
for (i = 1; ; i++)
{
@@ -63,8 +63,8 @@ void fmpz_poly_factor_squarefree(fmpz_poly_factor_t fac, const fmpz_poly_t F)
}
fmpz_poly_gcd(d, v, s);
- fmpz_poly_div(v, v, d);
- fmpz_poly_div(w, s, d);
+ fmpz_poly_divexact(v, v, d);
+ fmpz_poly_divexact(w, s, d);
if (d->length > 1)
fmpz_poly_factor_insert(fac, d, i);
diff --git a/src/fmpz_poly_mat/fflu.c b/src/fmpz_poly_mat/fflu.c
index 0ca3daeee3..161bc89d03 100644
--- a/src/fmpz_poly_mat/fflu.c
+++ b/src/fmpz_poly_mat/fflu.c
@@ -84,7 +84,7 @@ fmpz_poly_mat_fflu(fmpz_poly_mat_t B, fmpz_poly_t den, slong * perm,
fmpz_poly_mul(t, E(j, pivot_col), E(pivot_row, k));
fmpz_poly_sub(E(j, k), E(j, k), t);
if (pivot_row > 0)
- fmpz_poly_div(E(j, k), E(j, k), den);
+ fmpz_poly_divexact(E(j, k), E(j, k), den);
}
}
diff --git a/src/fmpz_poly_mat/rref.c b/src/fmpz_poly_mat/rref.c
index eee62c8b2d..a9ee28fce7 100644
--- a/src/fmpz_poly_mat/rref.c
+++ b/src/fmpz_poly_mat/rref.c
@@ -70,7 +70,7 @@ fmpz_poly_mat_rref(fmpz_poly_mat_t R, fmpz_poly_t den, const fmpz_poly_mat_t A)
fmpz_poly_sub(tmp, tmp, tmp2);
}
- fmpz_poly_div(fmpz_poly_mat_entry(R, i, nonpivots[k]),
+ fmpz_poly_divexact(fmpz_poly_mat_entry(R, i, nonpivots[k]),
tmp, fmpz_poly_mat_entry(R, i, pivots[i]));
}
}
diff --git a/src/fmpz_poly_mat/solve_fflu_precomp.c b/src/fmpz_poly_mat/solve_fflu_precomp.c
index fdf2e563c9..4a834e7def 100644
--- a/src/fmpz_poly_mat/solve_fflu_precomp.c
+++ b/src/fmpz_poly_mat/solve_fflu_precomp.c
@@ -66,7 +66,7 @@ fmpz_poly_mat_solve_fflu_precomp(fmpz_poly_mat_t X,
fmpz_poly_mul(T, LU(j, i), XX(i, k));
fmpz_poly_sub(XX(j, k), XX(j, k), T);
if (i > 0)
- fmpz_poly_div(XX(j, k), XX(j, k), LU(i-1, i-1));
+ fmpz_poly_divexact(XX(j, k), XX(j, k), LU(i-1, i-1));
}
}
@@ -79,7 +79,7 @@ fmpz_poly_mat_solve_fflu_precomp(fmpz_poly_mat_t X,
fmpz_poly_mul(T, XX(j, k), LU(i, j));
fmpz_poly_sub(XX(i, k), XX(i, k), T);
}
- fmpz_poly_div(XX(i, k), XX(i, k), LU(i, i));
+ fmpz_poly_divexact(XX(i, k), XX(i, k), LU(i, i));
}
}
diff --git a/src/fmpz_poly_q/add.c b/src/fmpz_poly_q/add.c
index 911d59c7ed..60a6d0249e 100644
--- a/src/fmpz_poly_q/add.c
+++ b/src/fmpz_poly_q/add.c
@@ -82,8 +82,8 @@ void fmpz_poly_q_add_in_place(fmpz_poly_q_t rop, const fmpz_poly_q_t op)
fmpz_poly_init(r2);
fmpz_poly_init(s2);
- fmpz_poly_div(r2, rop->den, d);
- fmpz_poly_div(s2, op->den, d);
+ fmpz_poly_divexact(r2, rop->den, d);
+ fmpz_poly_divexact(s2, op->den, d);
fmpz_poly_mul(rop->num, rop->num, s2);
fmpz_poly_mul(s2, op->num, r2); /* Using s2 as temp */
@@ -102,8 +102,8 @@ void fmpz_poly_q_add_in_place(fmpz_poly_q_t rop, const fmpz_poly_q_t op)
if (!fmpz_poly_is_one(r2))
{
- fmpz_poly_div(rop->num, rop->num, r2);
- fmpz_poly_div(rop->den, rop->den, r2);
+ fmpz_poly_divexact(rop->num, rop->num, r2);
+ fmpz_poly_divexact(rop->den, rop->den, r2);
}
}
fmpz_poly_clear(r2);
@@ -209,8 +209,8 @@ fmpz_poly_q_add(fmpz_poly_q_t rop,
fmpz_poly_init(r2);
fmpz_poly_init(s2);
- fmpz_poly_div(r2, op1->den, d); /* +ve leading coeff */
- fmpz_poly_div(s2, op2->den, d); /* +ve leading coeff */
+ fmpz_poly_divexact(r2, op1->den, d); /* +ve leading coeff */
+ fmpz_poly_divexact(s2, op2->den, d); /* +ve leading coeff */
fmpz_poly_mul(rop->num, op1->num, s2);
fmpz_poly_mul(rop->den, op2->num, r2); /* Using rop->den as temp */
@@ -229,8 +229,8 @@ fmpz_poly_q_add(fmpz_poly_q_t rop,
if (!fmpz_poly_is_one(r2))
{
- fmpz_poly_div(rop->num, rop->num, r2);
- fmpz_poly_div(rop->den, rop->den, r2);
+ fmpz_poly_divexact(rop->num, rop->num, r2);
+ fmpz_poly_divexact(rop->den, rop->den, r2);
}
}
diff --git a/src/fmpz_poly_q/canonicalise.c b/src/fmpz_poly_q/canonicalise.c
index 49cbf6ca25..ff1d5d8c4d 100644
--- a/src/fmpz_poly_q/canonicalise.c
+++ b/src/fmpz_poly_q/canonicalise.c
@@ -28,8 +28,8 @@ void fmpz_poly_q_canonicalise(fmpz_poly_q_t rop)
fmpz_poly_gcd(gcd, rop->num, rop->den);
if (!fmpz_poly_is_unit(gcd))
{
- fmpz_poly_div(rop->num, rop->num, gcd);
- fmpz_poly_div(rop->den, rop->den, gcd);
+ fmpz_poly_divexact(rop->num, rop->num, gcd);
+ fmpz_poly_divexact(rop->den, rop->den, gcd);
}
fmpz_poly_clear(gcd);
diff --git a/src/fmpz_poly_q/derivative.c b/src/fmpz_poly_q/derivative.c
index b951a9393c..4f3386736c 100644
--- a/src/fmpz_poly_q/derivative.c
+++ b/src/fmpz_poly_q/derivative.c
@@ -36,7 +36,7 @@ void fmpz_poly_q_derivative(fmpz_poly_q_t rop, const fmpz_poly_q_t op)
fmpz_poly_derivative(rhs, op->den);
fmpz_poly_gcd(d, rhs, op->den);
if (!fmpz_poly_is_one(d))
- fmpz_poly_div(rhs, rhs, d);
+ fmpz_poly_divexact(rhs, rhs, d);
fmpz_poly_mul(rhs, op->num, rhs);
fmpz_poly_derivative(rop->num, op->num);
@@ -48,7 +48,7 @@ void fmpz_poly_q_derivative(fmpz_poly_q_t rop, const fmpz_poly_q_t op)
else
{
fmpz_poly_init(lhs);
- fmpz_poly_div(lhs, op->den, d);
+ fmpz_poly_divexact(lhs, op->den, d);
fmpz_poly_mul(rop->num, rop->num, lhs);
fmpz_poly_mul(rop->den, op->den, lhs);
fmpz_poly_clear(lhs);
diff --git a/src/fmpz_poly_q/div.c b/src/fmpz_poly_q/div.c
index cfac02fdfd..83bd00fde1 100644
--- a/src/fmpz_poly_q/div.c
+++ b/src/fmpz_poly_q/div.c
@@ -78,9 +78,9 @@ void fmpz_poly_q_div(fmpz_poly_q_t rop,
}
else
{
- fmpz_poly_div(rop->num, op2->den, rop->den);
+ fmpz_poly_divexact(rop->num, op2->den, rop->den);
fmpz_poly_mul(rop->num, op1->num, rop->num);
- fmpz_poly_div(rop->den, op1->den, rop->den);
+ fmpz_poly_divexact(rop->den, op1->den, rop->den);
fmpz_poly_mul(rop->den, rop->den, op2->num);
}
}
@@ -90,9 +90,9 @@ void fmpz_poly_q_div(fmpz_poly_q_t rop,
if (fmpz_poly_is_one(rop->den))
{
- fmpz_poly_div(rop->den, op2->num, rop->num);
+ fmpz_poly_divexact(rop->den, op2->num, rop->num);
fmpz_poly_mul(rop->den, op1->den, rop->den);
- fmpz_poly_div(rop->num, op1->num, rop->num);
+ fmpz_poly_divexact(rop->num, op1->num, rop->num);
fmpz_poly_mul(rop->num, rop->num, op2->den);
}
else
@@ -101,11 +101,11 @@ void fmpz_poly_q_div(fmpz_poly_q_t rop,
fmpz_poly_init(t);
fmpz_poly_init(u);
- fmpz_poly_div(t, op1->num, rop->num);
- fmpz_poly_div(u, op2->num, rop->num);
- fmpz_poly_div(rop->num, op2->den, rop->den);
+ fmpz_poly_divexact(t, op1->num, rop->num);
+ fmpz_poly_divexact(u, op2->num, rop->num);
+ fmpz_poly_divexact(rop->num, op2->den, rop->den);
fmpz_poly_mul(rop->num, t, rop->num);
- fmpz_poly_div(rop->den, op1->den, rop->den);
+ fmpz_poly_divexact(rop->den, op1->den, rop->den);
fmpz_poly_mul(rop->den, rop->den, u);
fmpz_poly_clear(t);
fmpz_poly_clear(u);
diff --git a/src/fmpz_poly_q/mul.c b/src/fmpz_poly_q/mul.c
index 2bd2d29295..b971d3dab9 100644
--- a/src/fmpz_poly_q/mul.c
+++ b/src/fmpz_poly_q/mul.c
@@ -82,9 +82,9 @@ void fmpz_poly_q_mul(fmpz_poly_q_t rop,
}
else
{
- fmpz_poly_div(rop->num, op2->num, rop->den);
+ fmpz_poly_divexact(rop->num, op2->num, rop->den);
fmpz_poly_mul(rop->num, op1->num, rop->num);
- fmpz_poly_div(rop->den, op1->den, rop->den);
+ fmpz_poly_divexact(rop->den, op1->den, rop->den);
fmpz_poly_mul(rop->den, rop->den, op2->den);
}
}
@@ -94,9 +94,9 @@ void fmpz_poly_q_mul(fmpz_poly_q_t rop,
if (fmpz_poly_is_one(rop->den))
{
- fmpz_poly_div(rop->den, op2->den, rop->num);
+ fmpz_poly_divexact(rop->den, op2->den, rop->num);
fmpz_poly_mul(rop->den, op1->den, rop->den);
- fmpz_poly_div(rop->num, op1->num, rop->num);
+ fmpz_poly_divexact(rop->num, op1->num, rop->num);
fmpz_poly_mul(rop->num, rop->num, op2->num);
}
else
@@ -105,11 +105,11 @@ void fmpz_poly_q_mul(fmpz_poly_q_t rop,
fmpz_poly_init(t);
fmpz_poly_init(u);
- fmpz_poly_div(t, op1->num, rop->num);
- fmpz_poly_div(u, op2->den, rop->num);
- fmpz_poly_div(rop->num, op2->num, rop->den);
+ fmpz_poly_divexact(t, op1->num, rop->num);
+ fmpz_poly_divexact(u, op2->den, rop->num);
+ fmpz_poly_divexact(rop->num, op2->num, rop->den);
fmpz_poly_mul(rop->num, t, rop->num);
- fmpz_poly_div(rop->den, op1->den, rop->den);
+ fmpz_poly_divexact(rop->den, op1->den, rop->den);
fmpz_poly_mul(rop->den, rop->den, u);
fmpz_poly_clear(t);
fmpz_poly_clear(u);
diff --git a/src/fmpz_poly_q/sub.c b/src/fmpz_poly_q/sub.c
index 4ffa6548c6..373f10be1f 100644
--- a/src/fmpz_poly_q/sub.c
+++ b/src/fmpz_poly_q/sub.c
@@ -128,8 +128,8 @@ fmpz_poly_q_sub(fmpz_poly_q_t rop,
fmpz_poly_init(r2);
fmpz_poly_init(s2);
- fmpz_poly_div(r2, op1->den, d); /* +ve leading coeff */
- fmpz_poly_div(s2, op2->den, d); /* +ve leading coeff */
+ fmpz_poly_divexact(r2, op1->den, d); /* +ve leading coeff */
+ fmpz_poly_divexact(s2, op2->den, d); /* +ve leading coeff */
fmpz_poly_mul(rop->num, op1->num, s2);
fmpz_poly_mul(rop->den, op2->num, r2); /* Using rop->den as temp */
@@ -148,8 +148,8 @@ fmpz_poly_q_sub(fmpz_poly_q_t rop,
if (!fmpz_poly_is_one(r2))
{
- fmpz_poly_div(rop->num, rop->num, r2);
- fmpz_poly_div(rop->den, rop->den, r2);
+ fmpz_poly_divexact(rop->num, rop->num, r2);
+ fmpz_poly_divexact(rop->den, rop->den, r2);
}
}
diff --git a/src/gr/fmpz_poly.c b/src/gr/fmpz_poly.c
index 399850b2b5..4c94ff0b7d 100644
--- a/src/gr/fmpz_poly.c
+++ b/src/gr/fmpz_poly.c
@@ -509,7 +509,7 @@ _gr_fmpz_poly_divexact(fmpz_poly_t res, const fmpz_poly_t x, const fmpz_poly_t y
}
else
{
- fmpz_poly_div(res, x, y);
+ fmpz_poly_divexact(res, x, y);
return GR_SUCCESS;
}
}