solver first part

This commit is contained in:
hugogogo
2026-05-07 00:58:27 +02:00
parent 4c13d21e1f
commit 8c22b98d88
7 changed files with 102 additions and 31 deletions

View File

@@ -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 = ;