add gcd if all int

This commit is contained in:
hugogogo
2026-05-14 12:31:32 +02:00
parent d770d7fc87
commit bbe0d65b1f
7 changed files with 120 additions and 95 deletions

View File

@@ -11,31 +11,49 @@ static void print_solution_degree_1(s_solution_degree_1 solution)
static void print_solution_delta_zero(s_solution_degree_2 solution)
{
ft_printf("Discriminant is equal to zero, the solution is:\n");
printf("%g\n", solution.first_term);
printf("%g\n", solution.left_term);
}
static void print_solution_delta_positiv(s_solution_degree_2 solution)
{
ft_printf("Discriminant is strictly positive, the two solutions are:\n");
printf("%g\n", solution.first_term + solution.second_term);
printf("%g\n", solution.first_term - solution.second_term);
printf("%g\n", solution.left_term + solution.right_term);
printf("%g\n", solution.left_term - solution.right_term);
}
static void print_solution_delta_negativ(s_solution_degree_2 solution)
{
ft_printf("Discriminant is strictly negative, the two complex solutions are:\n");
// solution 1
if (solution.b)
printf("%g/%g + ", solution.b * -1, solution.a * 2);
printf("%gi/%g\n", solution.delta_sqrt, solution.a * 2);
if (solution.all_int)
{
// solution 1
if (solution.b != 0.0)
printf("%g/%g + ", solution.b * -1, solution.a * 2);
printf("%gi/%g\n", solution.delta_sqrt, solution.a * 2);
// solution 2
if (solution.b)
printf("%g/%g - ", solution.b * -1, solution.a * 2);
// solution 2
if (solution.b != 0.0)
printf("%g/%g - ", solution.b * -1, solution.a * 2);
else
printf("-");
printf("%gi/%g\n", solution.delta_sqrt, solution.a * 2);
}
else
printf("-");
printf("%gi/%g\n", solution.delta_sqrt, solution.a * 2);
{
// solution 1
if (solution.left_term != 0.0)
printf("%g + ", solution.left_term);
if (solution.right_term != 0.0)
printf("i * %g\n", solution.right_term);
// solution 2
if (solution.left_term != 0.0)
printf("%g - ", solution.left_term);
else
printf("-");
printf("i * %g\n", solution.right_term);
}
}
void print_solution(s_solution *solution)
@@ -53,11 +71,11 @@ void print_solution(s_solution *solution)
{
solution_d2 = solution->solution_degree_2;
delta_sign = solution_d2.delta_sign;
if (delta_sign == 0)
if (delta_sign == DELTA_ZERO)
print_solution_delta_zero(solution_d2);
else if (delta_sign > 0)
else if (delta_sign == DELTA_PLUS)
print_solution_delta_positiv(solution_d2);
else if (delta_sign < 0)
else if (delta_sign == DELTA_MINUS)
print_solution_delta_negativ(solution_d2);
else
stop_errors("delta sign is wrong : '%i' , delta : '%g'", solution_d2.delta_sign, solution_d2.delta);

View File

@@ -32,6 +32,36 @@ static double positiv_zero(double num)
return num;
}
int has_decimal_part(double num)
{
return (num != (int)num);
}
int any_has_decimal_part(double *num, size_t len)
{
while (len > 0)
{
if (has_decimal_part(num[len - 1]))
return 1;
len--;
}
return 0;
}
// find GCD of two integers using euclidean algorithm
static int gcd_int(int a, int b)
{
int tmp;
while (b != 0)
{
tmp = b;
b = a % b;
a = tmp;
}
return abs(a);
}
static void solve_degree_1(s_solution_degree_1 *solution, double a, double b)
{
solution->a = a;
@@ -44,6 +74,7 @@ static void solve_degree_2(s_solution_degree_2 *solution, double a, double b, do
{
double delta;
double delta_sqrt;
int gcd;
solution->a = a;
solution->b = b;
@@ -56,11 +87,37 @@ static void solve_degree_2(s_solution_degree_2 *solution, double a, double b, do
solution->delta_sqrt = ft_sqrt(solution->delta_absolute); // √|Δ|
delta_sqrt = solution->delta_sqrt;
// terms
if (b)
solution->first_term = positiv_zero(-b / (2 * a)); // -b / 2a
if (delta)
solution->second_term = positiv_zero(delta_sqrt / 2 * a); // √|Δ| / 2a
/**
* SOLVE LEFT AND RIGHT TERMS AS DOUBLES
*/
if (b != 0.0)
solution->left_term = positiv_zero(-b / (2 * a)); // -b / 2a
if (delta != 0.0)
solution->right_term = positiv_zero(delta_sqrt / 2 * a); // √|Δ| / 2a
/**
* COMPLEX : SOLVE TERMS AS FRACTIONS
*/
// check
if (solution->delta_sign != DELTA_MINUS)
return;
if (any_has_decimal_part((double[]){b, a, solution->delta_sqrt}, 3))
return;
solution->all_int = true;
// right term
gcd = gcd_int((int)solution->delta_sqrt, (int)(a * 2));
solution->right_term_numerator = solution->delta_sqrt / gcd;
solution->right_term_denominator = (a * 2) / gcd;
// left term
if (b == 0.0)
return;
gcd = gcd_int((int)b, (int)(a * 2));
solution->left_term_numerator = -b / gcd;
solution->left_term_denominator = (a * 2) / gcd;
}
void solve(const s_polynom *polynom, s_solution *solution)

View File

@@ -99,8 +99,14 @@ static void print_context_solution()
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 : %15g ( -b / 2a )\n", solution_d2.first_term);
dprintf(STDERR_FILENO, "second_term : %15g ( √|Δ| / 2a )\n", solution_d2.second_term);
dprintf(STDERR_FILENO, "left_term : %15g ( -b / 2a )\n", solution_d2.left_term);
dprintf(STDERR_FILENO, "right_term : %15g ( √|Δ| / 2a )\n", solution_d2.right_term);
dprintf(STDERR_FILENO, "all_int : %15i ( are int : b, a, √|Δ| )\n", solution_d2.all_int);
dprintf(STDERR_FILENO, "left_term_numerator : %15i ( -b / left_gcd )\n", solution_d2.left_term_numerator);
dprintf(STDERR_FILENO, "left_term_denominator : %15i ( 2a / left_gcd )\n", solution_d2.left_term_denominator);
dprintf(STDERR_FILENO, "right_term_numerator : %15i ( √|Δ| / right_gcd )\n", solution_d2.right_term_numerator);
dprintf(STDERR_FILENO, "right_term_denominator : %15i ( 2a / right_gcd )\n", solution_d2.right_term_denominator);
}
ft_putchar_fd('\n', STDERR_FILENO);