From 8c22b98d880d6d0061ccbfa40a386674451f892d Mon Sep 17 00:00:00 2001 From: hugogogo Date: Thu, 7 May 2026 00:58:27 +0200 Subject: [PATCH] solver first part --- Makefile | 1 + README.md | 12 +++--- headers/computorv1.h | 14 ++++--- libft | 2 +- src/launcher.c | 2 + src/solver.c | 92 +++++++++++++++++++++++++++++++++++++------- src/utils/errors.c | 10 ++--- 7 files changed, 102 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index f58d400..c53c086 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,7 @@ CC = gcc EXT = c CFLAGS = -Wall -Wextra -Werror $(INCLUDES) -g3 LFLAGS = -L$(D_LIB) -lft +LFLAGS += -lm # AUTOMATICALLY CREATED : D_OBJS = builds diff --git a/README.md b/README.md index dc6b33b..276628e 100644 --- a/README.md +++ b/README.md @@ -51,13 +51,13 @@ this project uses submodules (maybe recursively), so either : -> solution : - delta_sign; // + or - - delta_absolute; // |Δ| - - first_term_pgcd; // pgcd(b, 2a) - - first_term_numerator; // -b / pgcd - - first_term_denominator; // 2a / pgcd + - first_term_gcd; // gcd(b, 2a) + - first_term_numerator; // -b / gcd + - first_term_denominator; // 2a / gcd - first_term; // double (-b / 2a) - - second_term_pgcd; // pgcd(√|Δ|, 2a) - - second_term_numerator; // √|Δ| / pgcd - - second_term_denominator; // 2a / pgcd + - second_term_gcd; // gcd(√|Δ|, 2a) + - second_term_numerator; // √|Δ| / gcd + - second_term_denominator; // 2a / gcd - second_term; // double (√|Δ| / 2a) - double solution1; // first_term + second_term - double solution2; // first_term - second_term diff --git a/headers/computorv1.h b/headers/computorv1.h index 1838e5d..f14dede 100644 --- a/headers/computorv1.h +++ b/headers/computorv1.h @@ -10,6 +10,8 @@ #include // for errno #include // for strerror +#include // tmp + /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * MAIN.C */ @@ -117,13 +119,13 @@ typedef struct { e_delta_sign delta_sign; // DELTA_PLUS or DELTA_MINUS or DELTA_ZERO double delta_absolute; // |Δ| == |b² - 4ac| - int first_term_pgcd; // pgcd(b, 2a) - int first_term_numerator; // -b / pgcd - int first_term_denominator; // 2a / pgcd + int first_term_gcd; // gcd(b, 2a) + int first_term_numerator; // -b / gcd + int first_term_denominator; // 2a / gcd double first_term; // double (-b / 2a) - int second_term_pgcd; // pgcd(√|Δ|, 2a) - int second_term_numerator; // √|Δ| / pgcd - int second_term_denominator; // 2a / pgcd + int second_term_gcd; // gcd(√|Δ|, 2a) + int second_term_numerator; // √|Δ| / gcd + int second_term_denominator; // 2a / gcd double second_term; // double (√|Δ| / 2a) double solution1; // first_term + second_term double solution2; // first_term - second_term diff --git a/libft b/libft index f93c635..b768ac1 160000 --- a/libft +++ b/libft @@ -1 +1 @@ -Subproject commit f93c635234a70984bcd35d2f382a4dc67d94ba67 +Subproject commit b768ac1a141f853889660dfabdce0ad6e47be034 diff --git a/src/launcher.c b/src/launcher.c index ed68088..359e2d3 100644 --- a/src/launcher.c +++ b/src/launcher.c @@ -132,6 +132,8 @@ void launch_computorv1(char *input) polynom_fill_null(polynom, max_exponent); reduce(terms, polynom); + // print before solution + // solve s_solution solution[1]; solution_g_err = solution; diff --git a/src/solver.c b/src/solver.c index 0b07984..9c11cf9 100644 --- a/src/solver.c +++ b/src/solver.c @@ -2,16 +2,82 @@ #include "computorv1.h" +static int count_decimal_places(double num) +{ + // handle negative numbers + num = ft_fabs(num); + + // isolate the fractional part + double int_part; + double frac_part = ft_modf(num, &int_part); + + // if there is no fractional part, return 0 + if (frac_part == 0.0) + { + return 0; + } + + // count the number of decimal places + int count = 0; + const int max_decimals = 15; // prevent infinite loops for irrational numbers + while (count < max_decimals) + { + double dummy_frac_part = ft_modf(frac_part, NULL); + if (dummy_frac_part == 0.0) + { + break; + } + frac_part *= 10; + count++; + } + + return count; +} + +// find GCD of two integers (Euclidean algorithm) +static int gcd_int(int a, int b) +{ + while (b != 0) + { + int temp = b; + b = a % b; + a = temp; + } + return a; +} + +// find GCD of two doubles +static int find_gcd(double numerator, double denominator) +{ + // count decimal places for both numbers (eg. 2.5 -> 1 , and 1.12345 -> 5) + int num_decimals = count_decimal_places(numerator); + int den_decimals = count_decimal_places(denominator); + + // use the maximum precision (eg. 5) + int max_decimals = ft_greater(num_decimals, den_decimals); + + // scale the numbers to integers (eg. 2.5*100000=250000 and 1.12345*100000=112345) + // using ft_round because floating-point multiplication can introduce tiny precision errors + // (e.g., 0.3 * 10 = 2.9999999999999996 instead of 3.0). + // rounding ensures these errors are corrected before converting to integers. + double scale = ft_pow(10, max_decimals); + int num_scaled = (int)ft_round(numerator * scale); + int den_scaled = (int)ft_round(denominator * scale); + + // compute GCD of the scaled integers + return gcd_int(abs(num_scaled), ft_abs(den_scaled)); +} + /* e_delta_sign delta_sign; // DELTA_PLUS or DELTA_MINUS or DELTA_ZERO double delta_absolute; // |Δ| == |b² - 4ac| - int first_term_pgcd; // pgcd(b, 2a) - int first_term_numerator; // -b / pgcd - int first_term_denominator; // 2a / pgcd + int first_term_gcd; // gcd(b, 2a) + int first_term_numerator; // -b / gcd + int first_term_denominator; // 2a / gcd double first_term; // double (-b / 2a) - int second_term_pgcd; // pgcd(√|Δ|, 2a) - int second_term_numerator; // √|Δ| / pgcd - int second_term_denominator; // 2a / pgcd + int second_term_gcd; // gcd(√|Δ|, 2a) + int second_term_numerator; // √|Δ| / gcd + int second_term_denominator; // 2a / gcd double second_term; // double (√|Δ| / 2a) double solution1; // first_term + second_term double solution2; // first_term - second_term @@ -28,13 +94,13 @@ void solve(const double *polynom, s_solution *solution) b = polynom[1]; c = polynom[0]; delta = b * b - 4 * a * c; - solution->delta_sign = ft_sign(delta); - solution->delta_absolute = ft_abs(delta); - // solution->first_term_pgcd = find_pgcd(b, 2 * a); - // solution->first_term_numerator = ; - // solution->first_term_denominator = ; - // solution->first_term = ; - // solution->second_term_pgcd = ; + solution->delta_sign = ft_sign_f(delta); + solution->delta_absolute = ft_fabs(delta); + solution->first_term_gcd = find_gcd(b, 2 * a); + solution->first_term_numerator = -b / solution->first_term_gcd; + solution->first_term_denominator = 2 * a / solution->first_term_gcd; + solution->first_term = -b / (2 * a); + // solution->second_term_gcd = ; // solution->second_term_numerator = ; // solution->second_term_denominator = ; // solution->second_term = ; diff --git a/src/utils/errors.c b/src/utils/errors.c index c291720..6e3292c 100644 --- a/src/utils/errors.c +++ b/src/utils/errors.c @@ -73,11 +73,11 @@ static void print_context_solution() { dprintf(STDERR_FILENO, "delta_sign : %25s\n", delta_sign_to_str(solution_g_err->delta_sign)); dprintf(STDERR_FILENO, "delta_absolute : %25g\n", solution_g_err->delta_absolute); - // dprintf(STDERR_FILENO, "first_term_pgcd : %25g\n", solution_g_err->first_term_pgcd); - // dprintf(STDERR_FILENO, "first_term_numerator : %25g\n", solution_g_err->first_term_numerator); - // dprintf(STDERR_FILENO, "first_term_denominator : %25g\n", solution_g_err->first_term_denominator); - // dprintf(STDERR_FILENO, "first_term : %25g\n", solution_g_err->first_term); - // dprintf(STDERR_FILENO, "second_term_pgcd : %25g\n", solution_g_err->second_term_pgcd); + dprintf(STDERR_FILENO, "first_term_gcd : %25i\n", solution_g_err->first_term_gcd); + dprintf(STDERR_FILENO, "first_term_numerator : %25i\n", solution_g_err->first_term_numerator); + dprintf(STDERR_FILENO, "first_term_denominator : %25i\n", solution_g_err->first_term_denominator); + dprintf(STDERR_FILENO, "first_term : %25g\n", solution_g_err->first_term); + // dprintf(STDERR_FILENO, "second_term_gcd : %25g\n", solution_g_err->second_term_gcd); // dprintf(STDERR_FILENO, "second_term_numerator : %25g\n", solution_g_err->second_term_numerator); // dprintf(STDERR_FILENO, "second_term_denominator: %25g\n", solution_g_err->second_term_denominator); // dprintf(STDERR_FILENO, "second_term : %25g\n", solution_g_err->second_term);