Loading tests/testMoreIntegerP.cpp +16 −21 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ #include "IntegerP.h" using namespace std; const float PTS = 0.25; const float PTS = 1; float total = 0; /** Loading @@ -19,6 +19,7 @@ void scoreExample(string category, string test, T expected, T actual, float poin string score; if (expected == actual) { score = "CORRECT! +" + to_string(points); total += points; } else { score = "incorrect: +0"; Loading @@ -27,7 +28,7 @@ void scoreExample(string category, string test, T expected, T actual, float poin } // -------------------- Corner cases: representation of 1 and trailing zeros -------------------- bool test_a() { void test_a() { const string TEST_CATEGORY = "Corner: multiple representations of 1"; IntegerP one_default; Loading @@ -38,19 +39,14 @@ bool test_a() { IntegerP empty({}); // All should truncate to 1 if (one_default.trunc() != 1) scoreExample(TEST_CATEGORY, "default one trunc()",string("1"),to_string(one_default.trunc()),PTS); if (one_zero_list.trunc() != 1) scoreExample(TEST_CATEGORY, "IntegerP({0}).trunc()",string("1"),to_string(one_zero_list.trunc()),PTS); if (one_many_zeros.trunc() != 1) scoreExample(TEST_CATEGORY, "IntegerP({0,0,0}).trunc()",string("1"),to_string(one_many_zeros.trunc()),PTS); if (empty.trunc() != 1) scoreExample(TEST_CATEGORY, "IntegerP({}).trunc()",string("1"),to_string(empty.trunc()),PTS); // Check equality of 1's if (!(one_zero_list==one_many_zeros)) scoreExample(TEST_CATEGORY, "{0}=={0,0,0}", true, one_many_zeros==one_many_zeros,PTS); if (!(one_zero_list==empty)) scoreExample(TEST_CATEGORY, "{0}=={}", true, one_zero_list==empty,PTS); if (!(one_many_zeros==empty)) scoreExample(TEST_CATEGORY, "{0,0,0}=={}", true, one_many_zeros==empty,PTS); scoreExample(TEST_CATEGORY, "default one trunc()",string("1"),to_string(one_default.trunc()),PTS); scoreExample(TEST_CATEGORY, "IntegerP({0}).trunc()",string("1"),to_string(one_zero_list.trunc()),PTS); scoreExample(TEST_CATEGORY, "IntegerP({0,0,0}).trunc()",string("1"),to_string(one_many_zeros.trunc()),PTS); scoreExample(TEST_CATEGORY, "IntegerP({}).trunc()",string("1"),to_string(empty.trunc()),PTS); } // -------------------- Corner cases: identity element through operations -------------------- bool test_b() { void test_b() { string TEST_CATEGORY = "Corner: identity element via * and / with 1"; IntegerP one_default; // empty vector in your implementation Loading @@ -59,23 +55,21 @@ bool test_b() { // Multiplying by 1 should keep the value IntegerP p1 = x * one_default; if (p1.trunc() != 30) scoreExample(TEST_CATEGORY, "x * one_default trunc()",string("30"),to_string(p1.trunc()), PTS); scoreExample(TEST_CATEGORY, "x * one_default trunc()",string("30"),to_string(p1.trunc()), PTS); IntegerP p2 = x * one_zero_list; if (p2.trunc() != 30) scoreExample(TEST_CATEGORY, "x * IntegerP({0}) trunc()",string("30"),to_string(p2.trunc()), PTS); scoreExample(TEST_CATEGORY, "x * IntegerP({0}) trunc()",string("30"),to_string(p2.trunc()), PTS); // Dividing by 1 should keep the value IntegerP q1 = x / one_default; if (q1.trunc() != 30) scoreExample(TEST_CATEGORY, "x / one_default trunc()",string("30"),to_string(q1.trunc()), PTS); scoreExample(TEST_CATEGORY, "x / one_default trunc()",string("30"),to_string(q1.trunc()), PTS); IntegerP q2 = x / one_zero_list; if (q2.trunc() != 30) scoreExample(TEST_CATEGORY, "x / IntegerP({0}) trunc()",string("30"),to_string(q2.trunc()), PTS); scoreExample(TEST_CATEGORY, "x / IntegerP({0}) trunc()",string("30"),to_string(q2.trunc()), PTS); // Also check divisibleBy(1) is true for both representations of 1 if (!x.divisibleBy(one_default)) scoreExample(TEST_CATEGORY, "x.divisibleBy(one_default)","true","false", PTS); if (!x.divisibleBy(one_zero_list)) scoreExample(TEST_CATEGORY, "x.divisibleBy(IntegerP({0}))","true","false", PTS); scoreExample(TEST_CATEGORY, "x.divisibleBy(one_default)",true,x.divisibleBy(one_default), PTS); scoreExample(TEST_CATEGORY, "x.divisibleBy(IntegerP({0}))",true,x.divisibleBy(one_zero_list), PTS); } int main() { Loading @@ -83,4 +77,5 @@ int main() { test_b(); cout << "Total points: " << total << endl; return 0; } tests/testMoreRationalP.cpp +64 −34 Original line number Diff line number Diff line #include <iostream> #include <string> #include <climits> #include "RationalP.h" using namespace std; const float PTS = 0.25; float total = 0; /** * If expected == actual, increments the total by points. Prints out information about what happened * @param category The category of test * @param test The specific test * @param expected Expected outcome * @param actual Actual outcome * @param points Points for a correct response. */ template <typename T> void scoreExample(string category, string test, T expected, T actual, float points) { string score; if (expected == actual) { score = "CORRECT! +" + to_string(points); total += points; } else { score = "incorrect: +0"; } cout << category << " - " << test << ": " << score << endl; } bool test_8() { const char* T = "multiple representations of 1 (RationalP)"; /** * @return true when a and b are "approximately" equal */ bool approxEq(long double a, long double b) { if (a/b > 0.9 && a/b < 1.1) { return true; } else { return false; } } void test_a() { const char* TEST_CATEGORY = "multiple representations of 1 (RationalP)"; RationalP one_default; // default ctor RationalP one_zero_basis({0}); // explicitly basis with a trailing 0 // Both should approximate to 1.0 if (!approxEq(one_default.trunc(), 1.0L)) return failExample(T, "default one trunc()","1",to_string(one_default.trunc())); if (!approxEq(one_zero_basis.trunc(), 1.0L)) return failExample(T, "RationalP({0}).trunc()","1",to_string(one_zero_basis.trunc())); return true; scoreExample(TEST_CATEGORY, "default one trunc() approx 1",true, approxEq(one_default.trunc(), 1.0L), PTS); scoreExample(TEST_CATEGORY, "RationalP({0}).trunc() approx 1",true, approxEq(one_zero_basis.trunc(), 1.0L), PTS); } // -------------------- operations that produce 1 -------------------- bool test_9() { const char* T = "operations producing 1"; void test_b() { const char* TEST_CATEGORY = "operations producing 1"; // 3/4 * 4/3 = 1 RationalP a = RationalP::valueOf(3,4); Loading @@ -25,47 +61,41 @@ bool test_9() { RationalP prod = a * b; // should be about 1 if (!approxEq(prod.trunc(), 1.0L)) return failExample(T, "(3/4)*(4/3) trunc()","1",to_string(prod.trunc())); // toString() should be "1" for the identity element if (prod.toString() != "1") return failExample(T, "(3/4)*(4/3) toString()","1",prod.toString()); scoreExample(TEST_CATEGORY, "(3/4)*(4/3) trunc() approx 1",true, approxEq(prod.trunc(), 1.0L), PTS); scoreExample(TEST_CATEGORY, "(3/4)*(4/3) toString() == \"1\"",string("1"), prod.toString(), PTS); // Now create "1" via division: (7/3) / (7/3) = 1 RationalP c = RationalP::valueOf(7,3); RationalP quot = c / c; if (!approxEq(quot.trunc(), 1.0L)) return failExample(T, "(7/3)/(7/3) trunc()","1",to_string(quot.trunc())); if (quot.toString() != "1") return failExample(T, "(7/3)/(7/3) toString()","1",quot.toString()); return true; scoreExample(TEST_CATEGORY, "(7/3)/(7/3) trunc() approx 1",true, approxEq(quot.trunc(), 1.0L), PTS); scoreExample(TEST_CATEGORY, "(7/3)/(7/3) toString() == \"1\"",string("1"), quot.toString(), PTS); } // -------------------- trunc overflow / underflow -------------------- bool test_10() { const char* T = "Trunc overflow/underflow"; void test_c() { const char* TEST_CATEGORY = "Trunc overflow/underflow"; // Huge positive exponent: 2^20000 is astronomically large; trunc likely becomes inf RationalP huge_pos({20000}); long double v1 = huge_pos.trunc(); if (v1 < 0) return failExample(T, "2^20000 trunc() should not be negative","non-negative",to_string(v1)); scoreExample(TEST_CATEGORY, "2^20000 trunc() should be non-negative",true, (v1 >= 0), PTS); // Huge negative exponent: 2^-20000 ~ 0; trunc may underflow to 0 // Huge negative exponent: 2^-20000 ~ 0; RationalP huge_neg({-20000}); long double v2 = huge_neg.trunc(); if (v2 < 0) return failExample(T, "2^-20000 trunc() should not be negative","non-negative",to_string(v2)); // (2^20000)*(2^-20000) = 1 RationalP prod = huge_pos * huge_neg; if (!approxEq(prod.trunc(), 1.0L)) return failExample(T, "(2^20000)*(2^-20000) trunc()","1",to_string(prod.trunc())); return true; scoreExample(TEST_CATEGORY, "(2^20000)*(2^-20000) trunc() approx 1",true, approxEq(prod.trunc(), 1.0L), PTS); } int main() { test_a(); test_b(); test_c(); cout << "Total points: " << total << endl; return 0; } No newline at end of file Loading
tests/testMoreIntegerP.cpp +16 −21 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ #include "IntegerP.h" using namespace std; const float PTS = 0.25; const float PTS = 1; float total = 0; /** Loading @@ -19,6 +19,7 @@ void scoreExample(string category, string test, T expected, T actual, float poin string score; if (expected == actual) { score = "CORRECT! +" + to_string(points); total += points; } else { score = "incorrect: +0"; Loading @@ -27,7 +28,7 @@ void scoreExample(string category, string test, T expected, T actual, float poin } // -------------------- Corner cases: representation of 1 and trailing zeros -------------------- bool test_a() { void test_a() { const string TEST_CATEGORY = "Corner: multiple representations of 1"; IntegerP one_default; Loading @@ -38,19 +39,14 @@ bool test_a() { IntegerP empty({}); // All should truncate to 1 if (one_default.trunc() != 1) scoreExample(TEST_CATEGORY, "default one trunc()",string("1"),to_string(one_default.trunc()),PTS); if (one_zero_list.trunc() != 1) scoreExample(TEST_CATEGORY, "IntegerP({0}).trunc()",string("1"),to_string(one_zero_list.trunc()),PTS); if (one_many_zeros.trunc() != 1) scoreExample(TEST_CATEGORY, "IntegerP({0,0,0}).trunc()",string("1"),to_string(one_many_zeros.trunc()),PTS); if (empty.trunc() != 1) scoreExample(TEST_CATEGORY, "IntegerP({}).trunc()",string("1"),to_string(empty.trunc()),PTS); // Check equality of 1's if (!(one_zero_list==one_many_zeros)) scoreExample(TEST_CATEGORY, "{0}=={0,0,0}", true, one_many_zeros==one_many_zeros,PTS); if (!(one_zero_list==empty)) scoreExample(TEST_CATEGORY, "{0}=={}", true, one_zero_list==empty,PTS); if (!(one_many_zeros==empty)) scoreExample(TEST_CATEGORY, "{0,0,0}=={}", true, one_many_zeros==empty,PTS); scoreExample(TEST_CATEGORY, "default one trunc()",string("1"),to_string(one_default.trunc()),PTS); scoreExample(TEST_CATEGORY, "IntegerP({0}).trunc()",string("1"),to_string(one_zero_list.trunc()),PTS); scoreExample(TEST_CATEGORY, "IntegerP({0,0,0}).trunc()",string("1"),to_string(one_many_zeros.trunc()),PTS); scoreExample(TEST_CATEGORY, "IntegerP({}).trunc()",string("1"),to_string(empty.trunc()),PTS); } // -------------------- Corner cases: identity element through operations -------------------- bool test_b() { void test_b() { string TEST_CATEGORY = "Corner: identity element via * and / with 1"; IntegerP one_default; // empty vector in your implementation Loading @@ -59,23 +55,21 @@ bool test_b() { // Multiplying by 1 should keep the value IntegerP p1 = x * one_default; if (p1.trunc() != 30) scoreExample(TEST_CATEGORY, "x * one_default trunc()",string("30"),to_string(p1.trunc()), PTS); scoreExample(TEST_CATEGORY, "x * one_default trunc()",string("30"),to_string(p1.trunc()), PTS); IntegerP p2 = x * one_zero_list; if (p2.trunc() != 30) scoreExample(TEST_CATEGORY, "x * IntegerP({0}) trunc()",string("30"),to_string(p2.trunc()), PTS); scoreExample(TEST_CATEGORY, "x * IntegerP({0}) trunc()",string("30"),to_string(p2.trunc()), PTS); // Dividing by 1 should keep the value IntegerP q1 = x / one_default; if (q1.trunc() != 30) scoreExample(TEST_CATEGORY, "x / one_default trunc()",string("30"),to_string(q1.trunc()), PTS); scoreExample(TEST_CATEGORY, "x / one_default trunc()",string("30"),to_string(q1.trunc()), PTS); IntegerP q2 = x / one_zero_list; if (q2.trunc() != 30) scoreExample(TEST_CATEGORY, "x / IntegerP({0}) trunc()",string("30"),to_string(q2.trunc()), PTS); scoreExample(TEST_CATEGORY, "x / IntegerP({0}) trunc()",string("30"),to_string(q2.trunc()), PTS); // Also check divisibleBy(1) is true for both representations of 1 if (!x.divisibleBy(one_default)) scoreExample(TEST_CATEGORY, "x.divisibleBy(one_default)","true","false", PTS); if (!x.divisibleBy(one_zero_list)) scoreExample(TEST_CATEGORY, "x.divisibleBy(IntegerP({0}))","true","false", PTS); scoreExample(TEST_CATEGORY, "x.divisibleBy(one_default)",true,x.divisibleBy(one_default), PTS); scoreExample(TEST_CATEGORY, "x.divisibleBy(IntegerP({0}))",true,x.divisibleBy(one_zero_list), PTS); } int main() { Loading @@ -83,4 +77,5 @@ int main() { test_b(); cout << "Total points: " << total << endl; return 0; }
tests/testMoreRationalP.cpp +64 −34 Original line number Diff line number Diff line #include <iostream> #include <string> #include <climits> #include "RationalP.h" using namespace std; const float PTS = 0.25; float total = 0; /** * If expected == actual, increments the total by points. Prints out information about what happened * @param category The category of test * @param test The specific test * @param expected Expected outcome * @param actual Actual outcome * @param points Points for a correct response. */ template <typename T> void scoreExample(string category, string test, T expected, T actual, float points) { string score; if (expected == actual) { score = "CORRECT! +" + to_string(points); total += points; } else { score = "incorrect: +0"; } cout << category << " - " << test << ": " << score << endl; } bool test_8() { const char* T = "multiple representations of 1 (RationalP)"; /** * @return true when a and b are "approximately" equal */ bool approxEq(long double a, long double b) { if (a/b > 0.9 && a/b < 1.1) { return true; } else { return false; } } void test_a() { const char* TEST_CATEGORY = "multiple representations of 1 (RationalP)"; RationalP one_default; // default ctor RationalP one_zero_basis({0}); // explicitly basis with a trailing 0 // Both should approximate to 1.0 if (!approxEq(one_default.trunc(), 1.0L)) return failExample(T, "default one trunc()","1",to_string(one_default.trunc())); if (!approxEq(one_zero_basis.trunc(), 1.0L)) return failExample(T, "RationalP({0}).trunc()","1",to_string(one_zero_basis.trunc())); return true; scoreExample(TEST_CATEGORY, "default one trunc() approx 1",true, approxEq(one_default.trunc(), 1.0L), PTS); scoreExample(TEST_CATEGORY, "RationalP({0}).trunc() approx 1",true, approxEq(one_zero_basis.trunc(), 1.0L), PTS); } // -------------------- operations that produce 1 -------------------- bool test_9() { const char* T = "operations producing 1"; void test_b() { const char* TEST_CATEGORY = "operations producing 1"; // 3/4 * 4/3 = 1 RationalP a = RationalP::valueOf(3,4); Loading @@ -25,47 +61,41 @@ bool test_9() { RationalP prod = a * b; // should be about 1 if (!approxEq(prod.trunc(), 1.0L)) return failExample(T, "(3/4)*(4/3) trunc()","1",to_string(prod.trunc())); // toString() should be "1" for the identity element if (prod.toString() != "1") return failExample(T, "(3/4)*(4/3) toString()","1",prod.toString()); scoreExample(TEST_CATEGORY, "(3/4)*(4/3) trunc() approx 1",true, approxEq(prod.trunc(), 1.0L), PTS); scoreExample(TEST_CATEGORY, "(3/4)*(4/3) toString() == \"1\"",string("1"), prod.toString(), PTS); // Now create "1" via division: (7/3) / (7/3) = 1 RationalP c = RationalP::valueOf(7,3); RationalP quot = c / c; if (!approxEq(quot.trunc(), 1.0L)) return failExample(T, "(7/3)/(7/3) trunc()","1",to_string(quot.trunc())); if (quot.toString() != "1") return failExample(T, "(7/3)/(7/3) toString()","1",quot.toString()); return true; scoreExample(TEST_CATEGORY, "(7/3)/(7/3) trunc() approx 1",true, approxEq(quot.trunc(), 1.0L), PTS); scoreExample(TEST_CATEGORY, "(7/3)/(7/3) toString() == \"1\"",string("1"), quot.toString(), PTS); } // -------------------- trunc overflow / underflow -------------------- bool test_10() { const char* T = "Trunc overflow/underflow"; void test_c() { const char* TEST_CATEGORY = "Trunc overflow/underflow"; // Huge positive exponent: 2^20000 is astronomically large; trunc likely becomes inf RationalP huge_pos({20000}); long double v1 = huge_pos.trunc(); if (v1 < 0) return failExample(T, "2^20000 trunc() should not be negative","non-negative",to_string(v1)); scoreExample(TEST_CATEGORY, "2^20000 trunc() should be non-negative",true, (v1 >= 0), PTS); // Huge negative exponent: 2^-20000 ~ 0; trunc may underflow to 0 // Huge negative exponent: 2^-20000 ~ 0; RationalP huge_neg({-20000}); long double v2 = huge_neg.trunc(); if (v2 < 0) return failExample(T, "2^-20000 trunc() should not be negative","non-negative",to_string(v2)); // (2^20000)*(2^-20000) = 1 RationalP prod = huge_pos * huge_neg; if (!approxEq(prod.trunc(), 1.0L)) return failExample(T, "(2^20000)*(2^-20000) trunc()","1",to_string(prod.trunc())); return true; scoreExample(TEST_CATEGORY, "(2^20000)*(2^-20000) trunc() approx 1",true, approxEq(prod.trunc(), 1.0L), PTS); } int main() { test_a(); test_b(); test_c(); cout << "Total points: " << total << endl; return 0; } No newline at end of file