260 lines
8.1 KiB
C
260 lines
8.1 KiB
C
/* printer.c */
|
|
|
|
#include "computorv1.h"
|
|
|
|
/**
|
|
* DEGREE 1
|
|
*/
|
|
|
|
static void print_solution_degree_1(s_solution_degree_1 solution)
|
|
{
|
|
ft_printf("The solution is:\n");
|
|
printf("%g\n", solution.solution);
|
|
}
|
|
|
|
/**
|
|
* DEGREE 2 PURE
|
|
*/
|
|
|
|
static void print_solution_pure_radicand_zero()
|
|
{
|
|
ft_printf("Radicant is equal to zero, the solution is:\n");
|
|
printf("0\n");
|
|
}
|
|
|
|
static void print_solution_pure_radicand_positiv(s_solution_degree_2_pure solution)
|
|
{
|
|
double numerator;
|
|
double denominator;
|
|
|
|
ft_printf("Radicant is strictly positive, the two solutions are:\n");
|
|
if (solution.numerator_sqrt_is_int && solution.denominator_sqrt_is_int)
|
|
{
|
|
numerator = solution.numerator_sqrt;
|
|
denominator = solution.denominator_sqrt;
|
|
reduce_fraction(&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.denominator);
|
|
printf("-%g/√(%g)\n", solution.numerator_sqrt, solution.denominator);
|
|
}
|
|
else if (solution.denominator_sqrt_is_int)
|
|
{
|
|
printf("√(%g)/%g\n", solution.numerator, solution.denominator_sqrt);
|
|
printf("-√(%g)/%g\n", solution.numerator, solution.denominator_sqrt);
|
|
}
|
|
else
|
|
{
|
|
numerator = solution.numerator;
|
|
denominator = solution.denominator;
|
|
reduce_fraction(&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);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void print_solution_pure_radicand_negativ(s_solution_degree_2_pure solution)
|
|
{
|
|
double numerator;
|
|
double denominator;
|
|
|
|
ft_printf("Radicant is strictly negative, the two complex solutions are:\n");
|
|
if (solution.numerator_sqrt_is_int && solution.denominator_sqrt_is_int)
|
|
{
|
|
numerator = solution.numerator_sqrt;
|
|
denominator = solution.denominator_sqrt;
|
|
reduce_fraction(&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.denominator);
|
|
printf("-i%g/√(%g)\n", solution.numerator_sqrt, solution.denominator);
|
|
}
|
|
else if (solution.denominator_sqrt_is_int)
|
|
{
|
|
printf("i√(%g)/%g\n", solution.numerator, solution.denominator_sqrt);
|
|
printf("-i√(%g)/%g\n", solution.numerator, solution.denominator_sqrt);
|
|
}
|
|
else
|
|
{
|
|
numerator = solution.numerator;
|
|
denominator = solution.denominator;
|
|
reduce_fraction(&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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* DEGREE 2
|
|
*/
|
|
|
|
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", positiv_zero(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", positiv_zero(solution.left_term + solution.right_term));
|
|
printf("%g\n", positiv_zero(solution.left_term - solution.right_term));
|
|
}
|
|
|
|
static void print_solution_delta_negativ(s_solution_degree_2 solution)
|
|
{
|
|
double denominator;
|
|
double denominator_abs;
|
|
int denominator_sign;
|
|
double right_term_abs;
|
|
int right_term_sign;
|
|
bool has_first_term;
|
|
|
|
ft_printf("Discriminant is strictly negative, the two complex solutions are:\n");
|
|
|
|
has_first_term = false;
|
|
|
|
if (solution.all_int)
|
|
{
|
|
denominator = positiv_zero(solution.a * 2);
|
|
denominator_abs = ft_fabs(denominator);
|
|
denominator_sign = ft_fsign(denominator);
|
|
// solution 1
|
|
if (!is_nearly_equal_zero(solution.b))
|
|
{
|
|
has_first_term = true;
|
|
printf("%g/%g ", solution.b * -1 * denominator_sign, denominator_abs);
|
|
}
|
|
if (denominator_sign == -1)
|
|
printf("- ");
|
|
else if (has_first_term)
|
|
printf("+ "); // dont print '+' if it's first term
|
|
printf("%gi/%g\n", positiv_zero(solution.delta_sqrt), denominator_abs);
|
|
|
|
// solution 2
|
|
if (!is_nearly_equal_zero(solution.b))
|
|
{
|
|
has_first_term = true;
|
|
printf("%g/%g ", solution.b * -1 * denominator_sign, denominator_abs);
|
|
}
|
|
if (denominator_sign == 1)
|
|
printf("- ");
|
|
else if (has_first_term)
|
|
printf("+ "); // dont print '+' if it's first term
|
|
printf("%gi/%g\n", positiv_zero(solution.delta_sqrt), denominator_abs);
|
|
}
|
|
else
|
|
{
|
|
right_term_abs = positiv_zero(ft_fabs(solution.right_term));
|
|
right_term_sign = ft_fsign(solution.right_term);
|
|
|
|
// solution 1
|
|
if (!is_nearly_equal_zero(solution.left_term))
|
|
{
|
|
has_first_term = true;
|
|
printf("%g ", solution.left_term);
|
|
}
|
|
if (right_term_sign == -1)
|
|
printf("- ");
|
|
else if (has_first_term)
|
|
printf("+ "); // dont print '+' if it's first term
|
|
if (!is_nearly_equal_zero(right_term_abs))
|
|
printf("%g*i\n", right_term_abs);
|
|
|
|
// solution 2
|
|
if (!is_nearly_equal_zero(solution.left_term))
|
|
{
|
|
has_first_term = true;
|
|
printf("%g ", solution.left_term);
|
|
}
|
|
if (right_term_sign == 1)
|
|
printf("- ");
|
|
else if (has_first_term)
|
|
printf("+ "); // dont print '+' if it's first term
|
|
if (!is_nearly_equal_zero(right_term_abs))
|
|
printf("%g*i\n", right_term_abs);
|
|
}
|
|
}
|
|
|
|
void print_solution(s_solution *solution)
|
|
{
|
|
s_solution_degree_2 solution_d2;
|
|
s_solution_degree_2_pure solution_d2_pure;
|
|
e_delta_sign delta_sign;
|
|
e_radicand_sign radicand_sign;
|
|
|
|
// degree 1
|
|
|
|
if (solution->degree == 1)
|
|
{
|
|
return print_solution_degree_1(solution->solution_degree_1);
|
|
}
|
|
else if (solution->degree == 2 && solution->is_quadratic_pure)
|
|
{
|
|
solution_d2_pure = solution->solution_degree_2_pure;
|
|
radicand_sign = solution_d2_pure.radicand_sign;
|
|
if (radicand_sign == RADICAND_ZERO)
|
|
print_solution_pure_radicand_zero();
|
|
else if (radicand_sign == RADICAND_PLUS)
|
|
print_solution_pure_radicand_positiv(solution_d2_pure);
|
|
else if (radicand_sign == RADICAND_MINUS)
|
|
print_solution_pure_radicand_negativ(solution_d2_pure);
|
|
else
|
|
stop_errors("radicand sign is wrong : '%i' , radicand : '%g'", solution_d2_pure.radicand_sign, solution_d2_pure.radicand);
|
|
}
|
|
else if (solution->degree == 2 && !solution->is_quadratic_pure)
|
|
{
|
|
solution_d2 = solution->solution_degree_2;
|
|
delta_sign = solution_d2.delta_sign;
|
|
if (delta_sign == DELTA_ZERO)
|
|
print_solution_delta_zero(solution_d2);
|
|
else if (delta_sign == DELTA_PLUS)
|
|
print_solution_delta_positiv(solution_d2);
|
|
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);
|
|
}
|
|
else
|
|
{
|
|
stop_errors("The degree is '%i', it should already have been handled.", solution->degree);
|
|
}
|
|
} |