104 lines
3 KiB
C++
104 lines
3 KiB
C++
#include <iostream>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "fraction_toolbox.hpp"
|
|
|
|
using namespace std;
|
|
|
|
// read command line arguments
|
|
static void readcmdline(fraction & frac, int argc, char* argv[])
|
|
{
|
|
if (argc!=3)
|
|
{
|
|
printf("Usage: n d\n");
|
|
printf(" n numerator of fraction\n");
|
|
printf(" d denominator of fraction\n");
|
|
exit(1);
|
|
}
|
|
|
|
// read n
|
|
frac.num = atoi(argv[1]);
|
|
|
|
// read d
|
|
frac.denom = atoi(argv[2]);
|
|
}
|
|
|
|
static void test23467(int argc, char* argv[])
|
|
{
|
|
fraction frac;
|
|
readcmdline(frac, argc, argv);
|
|
|
|
cout << "#2: squared fraction" << endl;
|
|
print_fraction(square_fraction(frac));
|
|
|
|
cout << "#3: squared fraction in-place" << endl;
|
|
fraction frac2 = frac;
|
|
square_fraction_inplace(frac2);
|
|
print_fraction(frac2);
|
|
|
|
cout << "#4: fraction to double" << endl;
|
|
cout << fraction2double(frac) << endl;
|
|
|
|
cout << "#6: gcd of fraction" << endl;
|
|
cout << gcd(frac) << endl;
|
|
|
|
cout << "#7: fraction reduction in-place" << endl;
|
|
fraction frac3 = frac;
|
|
reduce_fraction_inplace(frac3);
|
|
print_fraction(frac3);
|
|
}
|
|
|
|
static void test5()
|
|
{
|
|
int a, b;
|
|
cout << "#5: recursive gcd of two integers" << endl;
|
|
cout << "Input first number: ";
|
|
cin >> a;
|
|
cout << "Input second number: ";
|
|
cin >> b;
|
|
cout << "GCD is: " << gcd(a, b) << endl;
|
|
}
|
|
|
|
static void test_array_functions(int n)
|
|
{
|
|
fraction* a = (fraction*) malloc(sizeof(fraction) * n);
|
|
fill_fraction_array(a, n);
|
|
|
|
cout << "Sum of array as fraction: " << endl;
|
|
print_fraction(sum_fraction_array(a, n));
|
|
|
|
cout << "Sum of array as double (approx.): " << endl;
|
|
cout << sum_fraction_array_approx(a, n) << endl;
|
|
|
|
// find n for which sum function breaks. Explain what is happening. n=1290
|
|
// this is the first number where the denominator overflows and thus
|
|
// erroneoulsly becomes a negative number. The overflow is caused by the
|
|
// sum_fractions function, specifically in the multiplication between
|
|
// denominators. The approximation function doesn't overflow since fractions
|
|
// are first converted into double floating point numbers, thus never
|
|
// calling the sum_fractions functions and performing dangerous fixed size
|
|
// integer multiplications. Additionally, due to the floating point nature
|
|
// of the double type, a sum of doubles will never overflow to something
|
|
// "weird", albeit precision will be lost due to the limited number of
|
|
// significant digits and for larger and larger values the sum will
|
|
// eventually reach the value "+Infinity" due to the fixed exponent size.
|
|
}
|
|
|
|
static void test_toolbox(int argc, char* argv[])
|
|
{
|
|
cout << "\n=============== test23467 =============== " << endl;
|
|
test23467(argc, argv);
|
|
|
|
cout << "\n================= test5 ================= " << endl;
|
|
test5();
|
|
|
|
cout << "\n========== test_array_functions ========= " << endl;
|
|
int n = 1290;
|
|
test_array_functions(n);
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
test_toolbox(argc, argv);
|
|
}
|