Midterm Project: Big Positive Real Number Calculator

Midterm-1: Big Positive Real Number in Decimal Point Format (40%)

  • Inputs:

    1. Input a big positive real number in decimal point format, one line for one number.
      1. digits before and after the decimal point are at most 9 digits, separated by a point character ..
    2. Input a operator, one line for one operator:
      1. +: add
      2. *: multiply
    3. The input is interleaved, one line for one number and one line for one operator after the number.
    4. Input Ctrl+D to finish the input.
      • Windows: Ctrl+Z (will show ^Z on the screen) then Enter ( in Format) to finish the input.
  • Outputs:

    1. The calculation result
      1. The result is shown in decimal point format, with at most 18 digits before the decimal point, and 9 digits after the decimal point (rounding toward zero, truncate).
      2. The format please refer to the Format section.
  • File name: midterm-1_<student_id>.cpp (e.g. midterm-1_106062802.cpp)

  • The program will not have any user prompts, only print the result.

  • The program does not need to handle invalid inputs.

  • The program should be finished within 10 seconds. Any test cases will garuntee the program is finished within 10 seconds.

Format

<before dec 1>.<after dec 1>⏎
<op 1>⏎
<before dec 2>.<after dec 2>⏎
<op 2>⏎
...
<before dec n-1>.<after dec n-1>⏎
<op n-1>⏎
<before dec n>.<after dec n>⏎
^Z⏎
<before dec result>.<after dec result>

Example

$ ./a.out
1.0⏎
^Z⏎
1.000000000
$ ./a.out
0.2⏎
^Z⏎
0.200000000
$ ./a.out
1.0⏎
+⏎
2.0⏎
+
3.0⏎
*⏎
4.3⏎
^Z⏎
25.800000000
$ ./a.out
1.000000001⏎
+⏎
2.000000002⏎
^Z⏎
3.000000003
$ ./a.out
123456789.123456789⏎
+⏎
987654321.987654321⏎
^Z⏎
1111111111.111111110
$ ./a.out
1.000000001⏎
*⏎
2.000000002⏎
^Z⏎
2.000000004
$ ./a.out
123456789.123456789⏎
*⏎
987654321.987654321⏎
^Z⏎
121932631356500531.347203169

Reference

Pseudo Code

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>

using namespace std;

class BigReal
{
private:
    // data members
    // save the digits before and after the decimal point of a before_decimal number
    // with `long long` precision
    const long long m_dec_upperbound = 1000000000;
    long long m_before_decimal;
    long long m_after_decimal; // times 10^-9
    void _output_normalization();

public:
    // Constructor, initializes before_decimal and after_decimalinary parts
    // hint: as like as `modify` function in examples
    // but use default constructor to implement
    BigReal(const long long &arg_before_decimal = 0.0,
            const long long &arg_after_decimal = 0.0);
    // Copy constructor
    BigReal(const BigReal &arg_big_real);
    // assignment operator
    BigReal &operator=(const BigReal &arg_big_real);
    // add assignment operator
    BigReal &operator+=(const BigReal &arg_big_real);
    // multiply assignment operator
    BigReal &operator*=(const BigReal &arg_big_real);
    // add function
    BigReal operator+(const BigReal &arg_big_real) const;
    // multiply function
    BigReal operator*(const BigReal &arg_big_real) const;
    // cout `<<` operator for print BigReal number
    // note: be careful about the format of output
    friend ostream &operator<<(ostream &arg_os, const BigReal &arg_big_real);
    // cin `>>` operator for input BigReal number
    // note: be careful about the format of input
    // hint: use string `+=` to append digits
    friend istream &operator>>(istream &arg_is, BigReal &arg_big_real);
};

int main()
{
    string input;
    BigReal result_complex;
    char op = '=';

    while (getline(cin, input))
    {
        // input is a operation
        if (input == "+" || input == "*")
        {
            op = input[0];
            continue;
        }
        else if (input.empty())
        {
            continue;
        }
        // input is a BigReal number
        else
        {
            stringstream ss(input);
            BigReal current_complex;
            ss >> current_complex;
            switch (op)
            {
            case '+':
                result_complex += current_complex;
                break;
            case '*':
                result_complex *= current_complex;
                break;
            case '=':
                result_complex = current_complex;
                break;
            default:
                cerr << "Error: unknown operation" << endl;
                return 1;
            }
        }
    }
    cout << endl;
    cout << result_complex << endl;
    return 0;
}

TA Version Code

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>

using namespace std;

class BigReal
{
private:
    // data members
    // save the digits before and after the decimal point of a before_decimal number
    // with `long long` precision
    const long long m_dec_upperbound = 1000000000;
    long long m_before_decimal;
    long long m_after_decimal; // times 10^-9
    void _output_normalization()
    {
        if (m_after_decimal < 0)
        {
            m_before_decimal -= 1;
            m_after_decimal += m_dec_upperbound;
        }
        if (m_after_decimal > m_dec_upperbound)
        {
            m_before_decimal += m_after_decimal / m_dec_upperbound;
            m_after_decimal = m_after_decimal % m_dec_upperbound;
        }
    }

public:
    // Constructor, initializes before_decimal and after_decimalinary parts
    // hint: as like as `modify` function in examples
    // but use default constructor to implement
    BigReal(const long long &arg_before_decimal = 0.0,
            const long long &arg_after_decimal = 0.0)
        : m_before_decimal(arg_before_decimal), m_after_decimal(arg_after_decimal)
    {
    }
    // Copy constructor
    BigReal(const BigReal &arg_big_real)
        : m_before_decimal(arg_big_real.m_before_decimal),
          m_after_decimal(arg_big_real.m_after_decimal)
    {
    }
    // assignment operator
    BigReal &operator=(const BigReal &arg_big_real)
    {
        if (this == &arg_big_real) // self-assignment
            return *this;
        m_before_decimal = arg_big_real.m_before_decimal;
        m_after_decimal = arg_big_real.m_after_decimal;
        return *this;
    }
    // add assignment operator
    BigReal &operator+=(const BigReal &arg_big_real)
    {
        m_before_decimal += arg_big_real.m_before_decimal;
        m_after_decimal += arg_big_real.m_after_decimal;
        _output_normalization();
        return *this;
    }
    // multiply assignment operator
    BigReal &operator*=(const BigReal &arg_big_real)
    {
        long long before_decimal = m_before_decimal * arg_big_real.m_before_decimal;
        long long after_decimal = m_after_decimal * arg_big_real.m_after_decimal / m_dec_upperbound;
        after_decimal += m_before_decimal * arg_big_real.m_after_decimal;
        after_decimal += m_after_decimal * arg_big_real.m_before_decimal;
        m_before_decimal = before_decimal;
        m_after_decimal = after_decimal;
        _output_normalization();
        return *this;
    }
    // add function
    BigReal operator+(const BigReal &arg_big_real) const
    {
        BigReal c(*this);
        c += arg_big_real;
        return c;
    }
    // multiply function
    BigReal operator*(const BigReal &arg_big_real) const
    {
        BigReal c(*this);
        c *= arg_big_real;
        return c;
    }
    // cout `<<` operator for print BigReal number
    // note: be careful about the format of output
    friend ostream &operator<<(ostream &arg_os, const BigReal &arg_big_real)
    {
        arg_os << arg_big_real.m_before_decimal << '.'
               << setfill('0') << setw(9) << arg_big_real.m_after_decimal;
        return arg_os;
    }
    // cin `>>` operator for input BigReal number
    // note: be careful about the format of input
    // hint: use string `+=` to append digits
    friend istream &operator>>(istream &arg_is, BigReal &arg_big_real)
    {
        string str_before_decimal, str_after_decimal;
        getline(arg_is, str_before_decimal, '.');
        getline(arg_is, str_after_decimal);
        str_after_decimal = str_after_decimal.substr(0, 9);
        for (int i = 0; i < 9; i++)
            if (i >= str_after_decimal.size())
                str_after_decimal += '0';
        arg_big_real.m_before_decimal = stoll(str_before_decimal);
        arg_big_real.m_after_decimal = stoll(str_after_decimal);
        return arg_is;
    }
};

int main()
{
    string input;
    BigReal result_complex;
    char op = '=';

    while (getline(cin, input))
    {
        // input is a operation
        if (input == "+" || input == "*")
        {
            op = input[0];
            continue;
        }
        else if (input.empty())
        {
            continue;
        }
        // input is a BigReal number
        else
        {
            stringstream ss(input);
            BigReal current_complex;
            ss >> current_complex;
            switch (op)
            {
            case '+':
                result_complex += current_complex;
                break;
            case '*':
                result_complex *= current_complex;
                break;
            case '=':
                result_complex = current_complex;
                break;
            default:
                cerr << "Error: unknown operation" << endl;
                return 1;
            }
        }
    }
    cout << endl;
    cout << result_complex << endl;
    return 0;
}