Blob Blame History Raw
From c7fd5866de31df5276eee01df09f657914fc4dab Mon Sep 17 00:00:00 2001
From: Gereon Kremer <gkremer@cs.stanford.edu>
Date: Thu, 6 Jan 2022 12:58:08 -0800
Subject: [PATCH 02/10] Fix issue with lp_algebraic_number_neg when number is
 actually rational

---
 src/number/algebraic_number.c         | 26 ++++++++++++++++++++------
 test/polyxx/test_algebraic_number.cpp | 11 +++++++++++
 2 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/src/number/algebraic_number.c b/src/number/algebraic_number.c
index 53199ae..1dde3fb 100644
--- a/src/number/algebraic_number.c
+++ b/src/number/algebraic_number.c
@@ -888,13 +888,27 @@ void lp_algebraic_number_sub(lp_algebraic_number_t* sub, const lp_algebraic_numb
 }
 
 void lp_algebraic_number_neg(lp_algebraic_number_t* neg, const lp_algebraic_number_t* a) {
-  lp_upolynomial_t* f_neg_x = 0;
 
-  if (a->f) {
-    f_neg_x = lp_upolynomial_subst_x_neg(a->f);
-    if (integer_sgn(lp_Z, lp_upolynomial_lead_coeff(f_neg_x)) < 0) {
-      lp_upolynomial_neg_in_place(f_neg_x);
-    }
+  if (a->f == 0)
+  {
+    lp_dyadic_rational_t rat_neg;
+    lp_algebraic_number_t a_neg;
+    lp_dyadic_rational_construct_copy(&rat_neg, &a->I.a);
+    dyadic_rational_neg(&rat_neg, &rat_neg);
+    lp_algebraic_number_construct_from_dyadic_rational(&a_neg, &rat_neg);
+
+    // store result
+    lp_algebraic_number_swap(neg, &a_neg);
+
+    // remove temps
+    lp_algebraic_number_destruct(&a_neg);
+    lp_dyadic_rational_destruct(&rat_neg);
+    return;
+  }
+
+  lp_upolynomial_t* f_neg_x = lp_upolynomial_subst_x_neg(a->f);
+  if (integer_sgn(lp_Z, lp_upolynomial_lead_coeff(f_neg_x)) < 0) {
+    lp_upolynomial_neg_in_place(f_neg_x);
   }
 
   lp_dyadic_interval_t I_neg; // To destroy
diff --git a/test/polyxx/test_algebraic_number.cpp b/test/polyxx/test_algebraic_number.cpp
index f0362a4..7a3847d 100644
--- a/test/polyxx/test_algebraic_number.cpp
+++ b/test/polyxx/test_algebraic_number.cpp
@@ -74,4 +74,15 @@ TEST_CASE("algebraic_number::floor") {
                               DyadicInterval(-2, -1))) == Integer(-2));
   CHECK(floor(AlgebraicNumber(UPolynomial({-2, 0, 1}), DyadicInterval(1, 2))) ==
         Integer(1));
+}
+TEST_CASE("algebraic_number::neg") {
+  AlgebraicNumber two(UPolynomial({-2, 1}), DyadicInterval(1, 3));
+  CHECK(-two == Rational(-2));
+
+  AlgebraicNumber sqrt2(UPolynomial({-2, 0, 1}), DyadicInterval(1, 2));
+  CHECK(-(sqrt2*sqrt2) == Rational(-2));
+
+  AlgebraicNumber msqrt2(UPolynomial({-2, 0, 1}), DyadicInterval(-2, -1));
+  CHECK(-sqrt2 == msqrt2);
+  CHECK(sqrt2 == -msqrt2);
 }
\ No newline at end of file
-- 
2.39.2