116 lines
2.7 KiB
C++
116 lines
2.7 KiB
C++
#include <iostream>
|
|
|
|
#include "fraction_toolbox.hpp"
|
|
|
|
void print_fraction(fraction frac)
|
|
{
|
|
std::cout << frac.num << '/' << frac.denom << std::endl;
|
|
}
|
|
|
|
void print_fraction_array(fraction frac_array[], int n)
|
|
{
|
|
std::cout << "[ " << frac_array[0].num << '/' << frac_array[0].denom << std::endl;
|
|
for (int i = 1; i < n-1; i++)
|
|
{
|
|
std::cout << " ";
|
|
print_fraction(frac_array[i]);
|
|
}
|
|
std::cout << " " << frac_array[n-1].num << '/' << frac_array[n-1].denom << " ]" << std::endl;
|
|
}
|
|
|
|
fraction square_fraction(fraction frac)
|
|
{
|
|
fraction square = { frac.num * frac.num, frac.denom * frac.denom };
|
|
return square;
|
|
}
|
|
|
|
void square_fraction_inplace(fraction& frac)
|
|
{
|
|
frac.num *= frac.num;
|
|
frac.denom *= frac.denom;
|
|
}
|
|
|
|
double fraction2double(fraction frac)
|
|
{
|
|
return (double) frac.num / (double) frac.denom;
|
|
}
|
|
|
|
int gcd(int a, int b)
|
|
{
|
|
return b == 0 ? a : gcd(b, a % b);
|
|
}
|
|
|
|
int gcd(fraction frac) {
|
|
int a = frac.num, b = frac.denom;
|
|
while (b != 0) {
|
|
int t = b;
|
|
b = a % b;
|
|
a = t;
|
|
}
|
|
return a;
|
|
}
|
|
|
|
void reduce_fraction_inplace(fraction & frac)
|
|
{
|
|
// the called function is the one implementing the iterative algorithm
|
|
// because gcd is called with one argument of type fraction (the reference
|
|
// is implicitly copied and passed by value), matching the signature of the
|
|
// iterative implementation
|
|
int g = gcd(frac);
|
|
|
|
frac.num /= g;
|
|
frac.denom /= g;
|
|
}
|
|
|
|
fraction add_fractions(fraction frac1, fraction frac2)
|
|
{
|
|
int d = frac1.denom;
|
|
|
|
frac1.num *= frac2.denom;
|
|
frac1.denom *= frac2.denom;
|
|
|
|
frac2.num *= d;
|
|
frac2.denom *= d;
|
|
|
|
fraction result = { frac1.num + frac2.num, frac1.denom };
|
|
reduce_fraction_inplace(result);
|
|
return result;
|
|
}
|
|
|
|
fraction sum_fraction_array(fraction frac_array[], int n) {
|
|
fraction sum = { 0, 1 };
|
|
for (int i = 0; i < n; i++) {
|
|
fraction frac = frac_array[i];
|
|
sum = add_fractions(sum, frac);
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
double sum_fraction_array_approx(fraction frac_array[], int n)
|
|
{
|
|
double sum = 0;
|
|
for (int i = 0; i < n; i++) {
|
|
sum += fraction2double(frac);
|
|
}
|
|
return sum;
|
|
|
|
// the approximation in this function is given by the fact that floating
|
|
// point numbers cannot represent precisely rational numbers due to the
|
|
// fixed size of significant digits they can hold in the mantissa. The
|
|
// approximation adds up for each fraction to double conversion performed in
|
|
// the loop
|
|
}
|
|
|
|
void fill_fraction_array(fraction frac_array[], int n)
|
|
{
|
|
fraction temp_frac;
|
|
temp_frac.num = 1;
|
|
temp_frac.denom = 1;
|
|
for (int i = 0; i <= n; i++)
|
|
{
|
|
temp_frac.denom = i * (i+1);
|
|
frac_array[i-1] = temp_frac;
|
|
}
|
|
}
|
|
|