This repository has been archived on 2022-10-18. You can view files and clone it, but cannot push or open issues or pull requests.
HPC/Project0/src/fraction_summing/fraction_toolbox.cpp
2022-09-21 11:51:41 +02:00

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;
}
}