]> www.ginac.de Git - ginac.git/commitdiff
[bugfix] factor_univariate(): handle polinomials over rationals (no segfaults any...
authorAlexei Sheplyakov <Alexei.Sheplyakov@gmail.com>
Sun, 28 Jul 2013 15:43:06 +0000 (18:43 +0300)
committerAlexei Sheplyakov <Alexei.Sheplyakov@gmail.com>
Sun, 28 Jul 2013 15:43:49 +0000 (18:43 +0300)
check/CMakeLists.txt
check/Makefile.am
check/factor_univariate_bug.cpp [new file with mode: 0644]
ginac/factor.cpp

index 0243617cb97710ff640645ef5904c252e469924b..0445a4a10f2a336bfabd0dcafa8f5ba0cd687bad 100644 (file)
@@ -33,6 +33,7 @@ set(ginac_tests
        exam_mod_gcd
        exam_cra
        bugme_chinrem_gcd
        exam_mod_gcd
        exam_cra
        bugme_chinrem_gcd
+       factor_univariate_bug
        pgcd_relatively_prime_bug
        pgcd_infinite_loop)
 
        pgcd_relatively_prime_bug
        pgcd_infinite_loop)
 
index 7aaed0717fe1b59dd3fd191af5b462800ed0484a..e17e5a59bde91354791798cb992af2c86503855d 100644 (file)
@@ -30,6 +30,7 @@ EXAMS = exam_paranoia \
        exam_misc \
        exam_mod_gcd \
        bugme_chinrem_gcd \
        exam_misc \
        exam_mod_gcd \
        bugme_chinrem_gcd \
+       factor_univariate_bug \
        pgcd_relatively_prime_bug \
        pgcd_infinite_loop \
        exam_cra
        pgcd_relatively_prime_bug \
        pgcd_infinite_loop \
        exam_cra
@@ -257,6 +258,9 @@ time_parser_LDADD = ../ginac/libginac.la
 bugme_chinrem_gcd_SOURCES = bugme_chinrem_gcd.cpp
 bugme_chinrem_gcd_LDADD = ../ginac/libginac.la
 
 bugme_chinrem_gcd_SOURCES = bugme_chinrem_gcd.cpp
 bugme_chinrem_gcd_LDADD = ../ginac/libginac.la
 
+factor_univariate_bug_SOURCES = factor_univariate_bug.cpp
+factor_univariate_bug_LDADD = ../ginac/libginac.la
+
 pgcd_relatively_prime_bug_SOURCES = pgcd_relatively_prime_bug.cpp
 pgcd_relatively_prime_bug_LDADD = ../ginac/libginac.la
 
 pgcd_relatively_prime_bug_SOURCES = pgcd_relatively_prime_bug.cpp
 pgcd_relatively_prime_bug_LDADD = ../ginac/libginac.la
 
diff --git a/check/factor_univariate_bug.cpp b/check/factor_univariate_bug.cpp
new file mode 100644 (file)
index 0000000..80a7ce4
--- /dev/null
@@ -0,0 +1,21 @@
+/**
+ * @file factor_upoly_q_bug.cpp Check for a bug in factor_univariate().
+ *
+ * factor_univariate() didn't check if the argument is an integer polynomial,
+ * the result was a segfault.
+ */
+#include "ginac.h"
+#include <iostream>
+using namespace GiNaC;
+using namespace std;
+
+int main(int argc, char** argv)
+{
+       cout << "checking if factor() handles rational polynomials. ";
+       parser p;
+       ex e = p("174247781*x^2-1989199947807987/200000000000000*x");
+       ex ef = factor(e);
+       ex diff = (e - ef).expand();
+       cout << "yes" << endl;
+       return 0;
+}
index 945b25e653a4c56ba59b1ec3abeac50f34a065f8..24f828cb793e9ad9d11e5104a4904d64345cd993 100644 (file)
@@ -1509,7 +1509,17 @@ static ex factor_univariate(const ex& poly, const ex& x, unsigned int& prime)
        cl_modint_ring R;
        unsigned int trials = 0;
        unsigned int minfactors = 0;
        cl_modint_ring R;
        unsigned int trials = 0;
        unsigned int minfactors = 0;
-       cl_I lc = lcoeff(prim) * the<cl_I>(ex_to<numeric>(cont).to_cl_N());
+
+       const numeric& cont_n = ex_to<numeric>(cont);
+       cl_I i_cont;
+       if (cont_n.is_integer()) {
+               i_cont = the<cl_I>(cont_n.to_cl_N());
+       } else {
+               // poly \in Q[x] => poly = q ipoly, ipoly \in Z[x], q \in Q
+               // factor(poly) \equiv q factor(ipoly)
+               i_cont = cl_I(1);
+       }
+       cl_I lc = lcoeff(prim)*i_cont;
        upvec factors;
        while ( trials < 2 ) {
                umodpoly modpoly;
        upvec factors;
        while ( trials < 2 ) {
                umodpoly modpoly;