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