Commit 105be35a authored by XingyuChen's avatar XingyuChen
Browse files

update testMoreIntegerP and testMoreRationalP

parent 8cc6195d
Loading
Loading
Loading
Loading

.DS_Store

0 → 100644
+6 KiB

File added.

No diff preview for this file type.

+18 −18
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
#include "IntegerP.h"
using namespace std;

const float PTS = 0.25;
const float PTS = 1;
float total = 0;

/**
@@ -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";
@@ -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;
@@ -38,19 +39,19 @@ 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);
    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);

    // 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, "{0}=={0,0,0}", true, one_zero_list==one_many_zeros,PTS);
    scoreExample(TEST_CATEGORY, "{0}=={}", true, one_zero_list==empty,PTS);
    scoreExample(TEST_CATEGORY, "{0,0,0}=={}", true, one_many_zeros==empty,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
@@ -59,23 +60,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() {
@@ -83,4 +82,5 @@ int main() {
    test_b();

    cout << "Total points:  " << total << endl;
    return 0;
}
 No newline at end of file
+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);
@@ -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