diff --git a/Makefile b/Makefile index 43f368c..2c50b48 100644 --- a/Makefile +++ b/Makefile @@ -103,43 +103,43 @@ $(NAME): $(OBJS) $(CC) $(OBJS) -o $@ $(LFLAGS) run: $(NAME) - @echo $(B_PURPLE)"\n---------------------------------------------\n1. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n1. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3 * x^2 + 5 * x^1 - 2 * x^0 = 5 * x^1" - @echo $(B_PURPLE)"\n---------------------------------------------\n2. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n2. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5 * x^1" - @echo $(B_PURPLE)"\n---------------------------------------------\n3. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n3. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3 * x^2 + 2 * x^2 = 5 * x^1" - @echo $(B_PURPLE)"\n---------------------------------------------\n4. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n4. flag -e SHOULD FAIL \n"$(RESET) -./$(NAME) $(RUN_FLAGS) -e "3 * x^2 + 2 * x - 7 * x^4 = 1 * x^4" - @echo $(B_PURPLE)"\n---------------------------------------------\n5. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n5. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3*x^2 + 2x = 0" - @echo $(B_PURPLE)"\n---------------------------------------------\n6. float coefficient \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n6. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5.123 * x^1" - @echo $(B_PURPLE)"\n---------------------------------------------\n7. float exponent SHOULD FAILS \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n7. float exponent SHOULD FAIL \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5 * x^1.2" - @echo $(B_PURPLE)"\n---------------------------------------------\n8. power 4 \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n8. degree 4 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3x^2 + 2x -7x^4 = x^4" - @echo $(B_PURPLE)"\n---------------------------------------------\n9. utf8 \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n9. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3x² + 2x -7x¹ = x" - @echo $(B_PURPLE)"\n---------------------------------------------\n10. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n10. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3x² + 2x -7 = x" - @echo $(B_PURPLE)"\n---------------------------------------------\n11. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n11. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "-3x² + 2x -7 = x" - @echo $(B_PURPLE)"\n---------------------------------------------\n12. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n12. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "+3x² + 2x -7 = x" - @echo $(B_PURPLE)"\n---------------------------------------------\n13. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n13. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3x² + 0x -7 = x" - @echo $(B_PURPLE)"\n---------------------------------------------\n14. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n14. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3x² + 0x -0 = x" - @echo $(B_PURPLE)"\n---------------------------------------------\n15. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n15. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3x² + 2x -0 = x" @echo $(B_PURPLE)"\n---------------------------------------------\n16. degree 1 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3x + 2x -0 = x" - @echo $(B_PURPLE)"\n---------------------------------------------\n17. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n17. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "3x² + x -0 = x" - @echo $(B_PURPLE)"\n---------------------------------------------\n18. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n18. degree 2 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "0x² + x -0 = x" - @echo $(B_PURPLE)"\n---------------------------------------------\n19. \n"$(RESET) + @echo $(B_PURPLE)"\n---------------------------------------------\n19. degree 5 SHOULD FAIL \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "2x⁵ + x -0 = -7x^5" @echo $(B_PURPLE)"\n---------------------------------------------\n20. degree 1 \n"$(RESET) -./$(NAME) $(RUN_FLAGS) "2x + x -0 = -7x" diff --git a/headers/computorv1.h b/headers/computorv1.h index 8563e46..d504810 100644 --- a/headers/computorv1.h +++ b/headers/computorv1.h @@ -136,7 +136,8 @@ typedef struct double b; // b in "ax² + bx + c" double c; // c in "ax² + bx + c" e_delta_sign delta_sign; // DELTA_PLUS or DELTA_MINUS or DELTA_ZERO - double delta_absolute; // |Δ| == |b² - 4ac| + double delta; // Δ == b² - 4ac + double delta_absolute; // |Δ| double delta_sqrt; // √|Δ| // int first_term_gcd; // gcd(b, 2a) diff --git a/libft b/libft index 45cc208..de28530 160000 --- a/libft +++ b/libft @@ -1 +1 @@ -Subproject commit 45cc208f4474d2d880f926f88c5baafb8852d50f +Subproject commit de2853025930ac6ea8ff54a12fe089cc3eb777e8 diff --git a/src/solver.c b/src/solver.c index 0cb1415..665b890 100644 --- a/src/solver.c +++ b/src/solver.c @@ -2,6 +2,13 @@ #include "computorv1.h" +static double positiv_zero(double num) +{ + if (num == 0) + return 0; + return num; +} + static int count_decimal_places(double num) { // handle negative numbers @@ -70,18 +77,13 @@ static int find_gcd(double numerator, double denominator) static void solve_degree_1(s_solution_degree_1 *solution, double a, double b) { - double value; - solution->a = a; solution->b = b; solution->solution_gcd = find_gcd(b, a); // gcd(b, a) solution->solution_numerator = -b / solution->solution_gcd; // -b / gcd solution->solution_denominator = a / solution->solution_gcd; // a / gcd - value = -b / a; - if (value == 0) - value = ft_fabs(value); - solution->solution = value; + solution->solution = positiv_zero(-b / a); // -b / a } static void solve_degree_2(s_solution_degree_2 *solution, double a, double b, double c) @@ -94,8 +96,9 @@ static void solve_degree_2(s_solution_degree_2 *solution, double a, double b, do solution->c = c; delta = b * b - 4 * a * c; + solution->delta = delta; // Δ == b² - 4ac solution->delta_sign = ft_fsign(delta); // DELTA_PLUS or DELTA_MINUS or DELTA_ZERO - solution->delta_absolute = ft_fabs(delta); // |Δ| == |b² - 4ac| + solution->delta_absolute = ft_fabs(delta); // |Δ| solution->delta_sqrt = ft_sqrt(solution->delta_absolute); // √|Δ| delta_sqrt = solution->delta_sqrt; @@ -103,25 +106,25 @@ static void solve_degree_2(s_solution_degree_2 *solution, double a, double b, do solution->first_term_gcd = find_gcd(b, 2 * a); // gcd(b, 2a) solution->first_term_numerator = -b / solution->first_term_gcd; // -b / gcd solution->first_term_denominator = 2 * a / solution->first_term_gcd; // 2a / gcd - solution->first_term = -b / (2 * a); // double (-b / 2a) + solution->first_term = positiv_zero(-b / (2 * a)); // -b / 2a // second term solution->second_term_gcd = find_gcd(delta_sqrt, 2 * a); // gcd(√|Δ|, 2a) solution->second_term_numerator = delta_sqrt / solution->second_term_gcd; // √|Δ| / gcd solution->second_term_denominator = 2 * a / solution->second_term_gcd; // 2a / gcd - solution->second_term = delta_sqrt / 2 * a; // √|Δ| / 2a + solution->second_term = positiv_zero(delta_sqrt / 2 * a); // √|Δ| / 2a // solution solution->solution1 = solution->first_term; // first_term + second_term if (solution->delta_sign == DELTA_ZERO) { - solution->solution1 = solution->first_term; // -b / 2a - solution->solution2 = NAN; // NAN (no solution) + solution->solution1 = positiv_zero(solution->first_term); // -b / 2a + solution->solution2 = NAN; // NAN (no solution) } else if (solution->delta_sign == DELTA_MINUS) { - solution->solution1 = solution->first_term + solution->second_term; // -b / 2a + i√|Δ| / 2a - solution->solution2 = solution->first_term - solution->second_term; // -b / 2a - i√|Δ| / 2a + solution->solution1 = positiv_zero(solution->first_term + solution->second_term); // -b / 2a + i√|Δ| / 2a + solution->solution2 = positiv_zero(solution->first_term - solution->second_term); // -b / 2a - i√|Δ| / 2a } else if (solution->delta_sign == DELTA_PLUS) { diff --git a/src/utils/errors.c b/src/utils/errors.c index 36b953b..88c026c 100644 --- a/src/utils/errors.c +++ b/src/utils/errors.c @@ -71,49 +71,50 @@ static void print_context_polynom() static void print_context_solution() { - s_solution_degree_1 solution_1; - s_solution_degree_2 solution_2; + s_solution_degree_1 solution_d1; + s_solution_degree_2 solution_d2; if (solution_g_err->degree == 1) { - solution_1 = solution_g_err->solution_degree_1; + solution_d1 = solution_g_err->solution_degree_1; dprintf(STDERR_FILENO, "degree 1 : x^1 ( ax + b )\n"); - dprintf(STDERR_FILENO, "a : %10g ( a )\n", solution_1.a); - dprintf(STDERR_FILENO, "b : %10g ( b )\n", solution_1.b); + dprintf(STDERR_FILENO, "a : %10g ( a )\n", solution_d1.a); + dprintf(STDERR_FILENO, "b : %10g ( b )\n", solution_d1.b); - dprintf(STDERR_FILENO, "gcd : %10i ( gcd( b, a ) )\n", solution_1.solution_gcd); - dprintf(STDERR_FILENO, "numerator : %10i ( -b / gcd )\n", solution_1.solution_numerator); - dprintf(STDERR_FILENO, "denominator : %10i ( a / gcd )\n", solution_1.solution_denominator); - dprintf(STDERR_FILENO, "solution : %10g ( -b / a )\n", solution_1.solution); + dprintf(STDERR_FILENO, "gcd : %10i ( gcd( b, a ) )\n", solution_d1.solution_gcd); + dprintf(STDERR_FILENO, "numerator : %10i ( -b / gcd )\n", solution_d1.solution_numerator); + dprintf(STDERR_FILENO, "denominator : %10i ( a / gcd )\n", solution_d1.solution_denominator); + dprintf(STDERR_FILENO, "solution : %10g ( -b / a )\n", solution_d1.solution); } else if (solution_g_err->degree == 2) { - solution_2 = solution_g_err->solution_degree_2; + solution_d2 = solution_g_err->solution_degree_2; dprintf(STDERR_FILENO, "degree 2 : delta > 0 ( -b / 2a +- √Δ / 2a )\n"); dprintf(STDERR_FILENO, " delta == 0 ( -b / 2a )\n"); dprintf(STDERR_FILENO, " delta < 0 ( -b / 2a +- i√|Δ| / 2a )\n"); - dprintf(STDERR_FILENO, "a : %15g ( a )\n", solution_2.a); - dprintf(STDERR_FILENO, "b : %15g ( b )\n", solution_2.b); - dprintf(STDERR_FILENO, "c : %15g ( c )\n", solution_2.c); + dprintf(STDERR_FILENO, "a : %15g ( a )\n", solution_d2.a); + dprintf(STDERR_FILENO, "b : %15g ( b )\n", solution_d2.b); + dprintf(STDERR_FILENO, "c : %15g ( c )\n", solution_d2.c); - dprintf(STDERR_FILENO, "delta_sign : %15s ( '-' || '+' || '0' )\n", delta_sign_to_str(solution_2.delta_sign)); - dprintf(STDERR_FILENO, "delta_absolute : %15g ( |Δ| == |b² - 4ac| )\n", solution_2.delta_absolute); - dprintf(STDERR_FILENO, "delta_sqrt : %15g ( √|Δ| )\n", solution_2.delta_sqrt); + dprintf(STDERR_FILENO, "delta : %15g ( Δ == b² - 4ac )\n", solution_d2.delta); + dprintf(STDERR_FILENO, "delta_sign : %15s ( '-' || '+' || '0' )\n", delta_sign_to_str(solution_d2.delta_sign)); + dprintf(STDERR_FILENO, "delta_absolute : %15g ( |Δ| )\n", solution_d2.delta_absolute); + dprintf(STDERR_FILENO, "delta_sqrt : %15g ( √|Δ| )\n", solution_d2.delta_sqrt); - dprintf(STDERR_FILENO, "first_term_gcd : %15i ( gcd( b, 2a ) )\n", solution_2.first_term_gcd); - dprintf(STDERR_FILENO, "first_term_numerator : %15i ( -b / gcd )\n", solution_2.first_term_numerator); - dprintf(STDERR_FILENO, "first_term_denominator : %15i ( 2a / gcd )\n", solution_2.first_term_denominator); - dprintf(STDERR_FILENO, "first_term : %15g ( -b / 2a )\n", solution_2.first_term); + dprintf(STDERR_FILENO, "first_term_gcd : %15i ( gcd( b, 2a ) )\n", solution_d2.first_term_gcd); + dprintf(STDERR_FILENO, "first_term_numerator : %15i ( -b / gcd )\n", solution_d2.first_term_numerator); + dprintf(STDERR_FILENO, "first_term_denominator : %15i ( 2a / gcd )\n", solution_d2.first_term_denominator); + dprintf(STDERR_FILENO, "first_term : %15g ( -b / 2a )\n", solution_d2.first_term); - dprintf(STDERR_FILENO, "second_term_gcd : %15i ( gcd(√|Δ|, 2a ) )\n", solution_2.second_term_gcd); - dprintf(STDERR_FILENO, "second_term_numerator : %15i ( √|Δ| / gcd )\n", solution_2.second_term_numerator); - dprintf(STDERR_FILENO, "second_term_denominator: %15i ( 2a / gcd )\n", solution_2.second_term_denominator); - dprintf(STDERR_FILENO, "second_term : %15g ( √|Δ| / 2a )\n", solution_2.second_term); + dprintf(STDERR_FILENO, "second_term_gcd : %15i ( gcd(√|Δ|, 2a ) )\n", solution_d2.second_term_gcd); + dprintf(STDERR_FILENO, "second_term_numerator : %15i ( √|Δ| / gcd )\n", solution_d2.second_term_numerator); + dprintf(STDERR_FILENO, "second_term_denominator: %15i ( 2a / gcd )\n", solution_d2.second_term_denominator); + dprintf(STDERR_FILENO, "second_term : %15g ( √|Δ| / 2a )\n", solution_d2.second_term); - dprintf(STDERR_FILENO, "solution1 : %15g ( (-b / 2a) + (√Δ / 2a) )\n", solution_2.solution1); - dprintf(STDERR_FILENO, "solution2 : %15g ( (-b / 2a) - (√Δ / 2a) )\n", solution_2.solution2); + dprintf(STDERR_FILENO, "solution1 : %15g ( (-b / 2a) + (√Δ / 2a) )\n", solution_d2.solution1); + dprintf(STDERR_FILENO, "solution2 : %15g ( (-b / 2a) - (√Δ / 2a) )\n", solution_d2.solution2); } ft_putchar_fd('\n', STDERR_FILENO); diff --git a/src/utils/printer.c b/src/utils/printer.c index c480167..0093231 100644 --- a/src/utils/printer.c +++ b/src/utils/printer.c @@ -160,12 +160,40 @@ void print_degree(s_polynom *polynom, int degree) void print_solution(s_solution *solution) { + s_solution_degree_1 solution_d1; + s_solution_degree_2 solution_d2; + if (solution->degree == 1) { + solution_d1 = solution->solution_degree_1; ft_printf("The solution is:\n"); - printf("%g\n", solution->solution_degree_1.solution); + printf("%g\n", solution_d1.solution); + return; } - else if (solution->degree == 2) + else if (solution->degree != 2) { + stop_errors("The degree is '%i', it should already have been handled.", solution->degree); + } + + // degree 2 + + solution_d2 = solution->solution_degree_2; + if (solution_d2.delta_sign == 0) + { + ft_printf("Discriminant is equal to zero, the solution is:\n"); + printf("%g\n", solution_d2.solution1); + } + else if (solution_d2.delta_sign > 0) + { + ft_printf("Discriminant is strictly positive, the two solutions are:\n"); + printf("%g\n%g\n", solution_d2.solution1, solution_d2.solution2); + } + else if (solution_d2.delta_sign < 0) + { + ft_printf("Discriminant is strictly negative, the two complex solutions are:\n"); + } + else + { + stop_errors("delta sign is wrong : '%i' , delta : '%g'", solution_d2.delta_sign, solution_d2.delta); } } \ No newline at end of file