From aa78af4e0fb91280317b3381d18478f42c6e91ca Mon Sep 17 00:00:00 2001 From: hugogogo Date: Thu, 14 May 2026 23:43:58 +0200 Subject: [PATCH] pure quadratic is working --- Makefile | 2 +- headers/computorv1.h | 11 ++++--- src/printer_solutions.c | 72 +++++++++++++++++++++++++++++------------ src/solver.c | 6 ++-- src/utils/errors.c | 10 +++--- src/utils/math.c | 7 +++- tester.sh | 14 ++++---- 7 files changed, 83 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index 73861e6..92d8a25 100644 --- a/Makefile +++ b/Makefile @@ -108,7 +108,7 @@ run: $(NAME) test: $(NAME) @echo $(B_PURPLE)"\n---------------------------------------------\nlaunch tests\n"$(RESET) - -@bash tester.sh + -@bash tester.sh --skip-reduced clean: $(RM_OBJS) diff --git a/headers/computorv1.h b/headers/computorv1.h index 3a1053e..ab93229 100644 --- a/headers/computorv1.h +++ b/headers/computorv1.h @@ -164,10 +164,12 @@ typedef struct e_radicand_sign radicand_sign; // RADICAND_PLUS or RADICAND_MINUS or RADICAND_ZERO double radicand_absolute; // |radicand| double radicand_sqrt; // √|radicand| - double numerator_sqrt; // √a - bool numerator_sqrt_is_int; // false if √a is a double - double denominator_sqrt; // √c - bool denominator_sqrt_is_int; // false if √c is a double + double numerator; // |c| + double numerator_sqrt; // √c + bool numerator_sqrt_is_int; // false if √c is a double + double denominator; // |a| + double denominator_sqrt; // √a + bool denominator_sqrt_is_int; // false if √a is a double } s_solution_degree_2_pure; typedef struct @@ -188,6 +190,7 @@ void solve(const s_polynom *polynom, s_solution *solution); * UTILS/MATH.C */ +bool is_nearly_equal(double num, int compare); bool is_nearly_equal_zero(double num); bool has_decimal_part(double num); bool any_has_decimal_part(double *num, size_t len); diff --git a/src/printer_solutions.c b/src/printer_solutions.c index 996d86e..4e8853a 100644 --- a/src/printer_solutions.c +++ b/src/printer_solutions.c @@ -33,26 +33,42 @@ static void print_solution_pure_radicand_positiv(s_solution_degree_2_pure soluti numerator = solution.numerator_sqrt; denominator = solution.denominator_sqrt; reduce_fraction(&numerator, &denominator); - printf("%g/%g\n", numerator, denominator); - printf("-%g/%g\n", numerator, denominator); + if (is_nearly_equal(denominator, 1)) + { + printf("%g\n", numerator); + printf("-%g\n", numerator); + } + else + { + printf("%g/%g\n", numerator, denominator); + printf("-%g/%g\n", numerator, denominator); + } } else if (solution.numerator_sqrt_is_int) { - printf("%g/√(%g)\n", solution.numerator_sqrt, solution.c); - printf("-%g/√(%g)\n", solution.numerator_sqrt, solution.c); + printf("%g/√(%g)\n", solution.numerator_sqrt, solution.denominator); + printf("-%g/√(%g)\n", solution.numerator_sqrt, solution.denominator); } else if (solution.denominator_sqrt_is_int) { - printf("√(%g)/%g\n", solution.a, solution.denominator_sqrt); - printf("-√(%g)/%g\n", solution.a, solution.denominator_sqrt); + printf("√(%g)/%g\n", solution.numerator, solution.denominator_sqrt); + printf("-√(%g)/%g\n", solution.numerator, solution.denominator_sqrt); } else { - numerator = solution.numerator_sqrt; - denominator = solution.denominator_sqrt; + numerator = solution.numerator; + denominator = solution.denominator; reduce_fraction(&numerator, &denominator); - printf("√(%g/%g)\n", numerator, denominator); - printf("-√(%g/%g)\n", numerator, denominator); + if (is_nearly_equal(denominator, 1)) + { + printf("√(%g)\n", numerator); + printf("-√(%g)\n", numerator); + } + else + { + printf("√(%g/%g)\n", numerator, denominator); + printf("-√(%g/%g)\n", numerator, denominator); + } } } @@ -67,26 +83,42 @@ static void print_solution_pure_radicand_negativ(s_solution_degree_2_pure soluti numerator = solution.numerator_sqrt; denominator = solution.denominator_sqrt; reduce_fraction(&numerator, &denominator); - printf("i%g/%g\n", numerator, denominator); - printf("-i%g/%g\n", numerator, denominator); + if (is_nearly_equal(denominator, 1)) + { + printf("i%g\n", numerator); + printf("-i%g\n", numerator); + } + else + { + printf("i%g/%g\n", numerator, denominator); + printf("-i%g/%g\n", numerator, denominator); + } } else if (solution.numerator_sqrt_is_int) { - printf("i%g/√(%g)\n", solution.numerator_sqrt, solution.c); - printf("-i%g/√(%g)\n", solution.numerator_sqrt, solution.c); + printf("i%g/√(%g)\n", solution.numerator_sqrt, solution.denominator); + printf("-i%g/√(%g)\n", solution.numerator_sqrt, solution.denominator); } else if (solution.denominator_sqrt_is_int) { - printf("i√(%g)/%g\n", solution.a, solution.denominator_sqrt); - printf("-i√(%g)/%g\n", solution.a, solution.denominator_sqrt); + printf("i√(%g)/%g\n", solution.numerator, solution.denominator_sqrt); + printf("-i√(%g)/%g\n", solution.numerator, solution.denominator_sqrt); } else { - numerator = solution.a; - denominator = solution.c; + numerator = solution.numerator; + denominator = solution.denominator; reduce_fraction(&numerator, &denominator); - printf("i√(%g/%g)\n", numerator, denominator); - printf("-i√(%g/%g)\n", numerator, denominator); + if (is_nearly_equal(denominator, 1)) + { + printf("i√(%g)\n", numerator); + printf("-i√(%g)\n", numerator); + } + else + { + printf("i√(%g/%g)\n", numerator, denominator); + printf("-i√(%g/%g)\n", numerator, denominator); + } } } diff --git a/src/solver.c b/src/solver.c index 91b7431..f70337f 100644 --- a/src/solver.c +++ b/src/solver.c @@ -106,9 +106,11 @@ static void solve_degree_2_pure(s_solution_degree_2_pure *solution, double a, do * SQARE ROOTS */ - solution->numerator_sqrt = ft_sqrt(a, DOUBLE_PRECISION); + solution->numerator = ft_fabs(c); + solution->numerator_sqrt = ft_sqrt(ft_fabs(c), DOUBLE_PRECISION); solution->numerator_sqrt_is_int = !has_decimal_part(solution->numerator_sqrt); - solution->denominator_sqrt = ft_sqrt(c, DOUBLE_PRECISION); + solution->denominator = ft_fabs(a); + solution->denominator_sqrt = ft_sqrt(ft_fabs(a), DOUBLE_PRECISION); solution->denominator_sqrt_is_int = !has_decimal_part(solution->denominator_sqrt); } diff --git a/src/utils/errors.c b/src/utils/errors.c index e30d46e..85db08e 100644 --- a/src/utils/errors.c +++ b/src/utils/errors.c @@ -101,10 +101,12 @@ static void print_context_solution() dprintf(STDERR_FILENO, "radicand_absolute : %15g ( |r| )\n", solution_d2_pure.radicand_absolute); dprintf(STDERR_FILENO, "radicand_sqrt : %15g ( √|r| )\n", solution_d2_pure.radicand_sqrt); - dprintf(STDERR_FILENO, "numerator_sqrt : %15g ( √a )\n", solution_d2_pure.numerator_sqrt); - dprintf(STDERR_FILENO, "numerator_sqrt_is_int : %15i ( false if √a is double )\n", solution_d2_pure.numerator_sqrt_is_int); - dprintf(STDERR_FILENO, "denominator_sqrt : %15g ( √c )\n", solution_d2_pure.denominator_sqrt); - dprintf(STDERR_FILENO, "denominator_sqrt_is_int: %15i ( false if √c is double )\n", solution_d2_pure.denominator_sqrt_is_int); + dprintf(STDERR_FILENO, "numerator : %15g ( |c| )\n", solution_d2_pure.numerator); + dprintf(STDERR_FILENO, "numerator_sqrt : %15g ( √c )\n", solution_d2_pure.numerator_sqrt); + dprintf(STDERR_FILENO, "numerator_sqrt_is_int : %15i ( false if √c is double )\n", solution_d2_pure.numerator_sqrt_is_int); + dprintf(STDERR_FILENO, "denominator : %15g ( |a| )\n", solution_d2_pure.denominator); + dprintf(STDERR_FILENO, "denominator_sqrt : %15g ( √a )\n", solution_d2_pure.denominator_sqrt); + dprintf(STDERR_FILENO, "denominator_sqrt_is_int: %15i ( false if √a is double )\n", solution_d2_pure.denominator_sqrt_is_int); } else { diff --git a/src/utils/math.c b/src/utils/math.c index 2e049df..56476b7 100644 --- a/src/utils/math.c +++ b/src/utils/math.c @@ -2,6 +2,11 @@ #include "computorv1.h" +bool is_nearly_equal(double num, int compare) +{ + return is_nearly_equal_zero(num - compare); +} + bool is_nearly_equal_zero(double num) { if (num > DOUBLE_PRECISION) @@ -13,7 +18,7 @@ bool is_nearly_equal_zero(double num) bool has_decimal_part(double num) { - return (num != (int)num); + return (!is_nearly_equal(num, (int)num)); } bool any_has_decimal_part(double *num, size_t len) diff --git a/tester.sh b/tester.sh index 142e3da..087210e 100644 --- a/tester.sh +++ b/tester.sh @@ -330,7 +330,7 @@ run_test \ "3 * x^2 + 5 * x^1 - 2 * x^0 = 5 * x" "\ Reduced form: -2 * x^0 + 0 * x^1 + 3 * x^2 = 0 Polynomial degree: 2 -Discriminant is strictly positive, the two solutions are: +Radicant is strictly positive, the two solutions are: √(2/3) -√(2/3)" @@ -339,16 +339,16 @@ run_test \ "9 * x^2 + 5 * x^1 - 2 * x^0 = 5 * x" "\ Reduced form: -2 * x^0 + 0 * x^1 + 9 * x^2 = 0 Polynomial degree: 2 -Discriminant is strictly positive, the two solutions are: -(√2)/3 --(√2)/3" +Radicant is strictly positive, the two solutions are: +√(2)/3 +-√(2)/3" run_test \ "28. degree 2 pure" \ "3 * x^2 + 5 * x^1 - 4 * x^0 = 5 * x" "\ Reduced form: -4 * x^0 + 0 * x^1 + 3 * x^2 = 0 Polynomial degree: 2 -Discriminant is strictly positive, the two solutions are: +Radicant is strictly positive, the two solutions are: 2/√(3) -2/√(3)" @@ -358,7 +358,7 @@ run_test \ "16 * x^2 + 5 * x^1 - 4 * x^0 = 5 * x" "\ Reduced form: -4 * x^0 + 0 * x^1 + 3 * x^2 = 0 Polynomial degree: 2 -Discriminant is strictly positive, the two solutions are: +Radicant is strictly positive, the two solutions are: 1/2 -1/2" @@ -368,6 +368,6 @@ run_test \ "4 * x^2 + 5 * x^1 - 16 * x^0 = 5 * x" "\ Reduced form: -4 * x^0 + 0 * x^1 + 3 * x^2 = 0 Polynomial degree: 2 -Discriminant is strictly positive, the two solutions are: +Radicant is strictly positive, the two solutions are: 2 -2"