Lab 7: 真・大數四則運算

  • 輸入:
    1. 要執行的計算功能,分別如下:
      1. 僅顯示兩數 (display only) (35%)
      2. 加 (+) (25%)
      3. 減 (-) (20%)
      4. 乘 (*) (10%)
      5. 除 (/) (10%)
    2. 兩整數 \( a, b \),兩整數不多於 10,000 位數字。。
  • 輸出:所選擇的功能 (i.e. display only, +, -, *, /)及兩整數 \( a, b \) 的運算結果,結果為整數。。
  • 檔名:lab7_1_<學號>.cpp (e.g. lab7_1_106062802.cpp)

程式需提示使用者輸入需要的運算功能,輸出該運算功能及兩整數 \( a, b \) 的運算結果。 程式需檢查使用者輸入的是否符合題目要求,不合法的輸入需在當下的輸入完成後顯示 Invalid input: 以及錯誤的輸入並結束程式。 不合法輸出格式範例請參考以下範例。 使用者會在每次輸入時輸入任意非空白 (i.e. 非 space, tab) 字元。 程式需在 30 秒之內執行完畢,所有測資皆不會超過 30 秒的執行時間。

Format

Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: <1-5>⏎
You selected: <display only,+, -, *, />
Input integer number (a): <a>⏎
Input integer number (b): <b>⏎
(a) = <a>
(b) = <b>
(a) <+, -, *, /> (b) = <result>

Example

Display

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 1⏎
You selected: display only
Input integer number (a): 123456789012345678901234567890⏎
Input integer number (b): 987654321098765432109876543210⏎
(a) = 123456789012345678901234567890
(b) = 987654321098765432109876543210

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 1⏎
You selected: display only
Input integer number (a): -0000000000000
Input integer number (b): -00000001
(a) = 0
(b) = -1

Plus

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 2⏎
You selected: +
Input integer number (a): 123456789012345678901234567890⏎
Input integer number (b): 987654321098765432109876543210⏎
(a) = 123456789012345678901234567890
(b) = 987654321098765432109876543210
(a) + (b) = 1111111110111111111011111111100

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 2⏎
You selected: +
Input integer number (a): 123456789012345678901234567890⏎
Input integer number (b): -987654321098765432109876543210⏎
(a) = 123456789012345678901234567890
(b) = -987654321098765432109876543210
(a) + (b) = -864197532086419753208641975320

Minus

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 3⏎
You selected: -
Input integer number (a): 123456789012345678901234567890⏎
Input integer number (b): 987654321098765432109876543210⏎
(a) = 123456789012345678901234567890
(b) = 987654321098765432109876543210
(a) - (b) = -864197532086419753208641975320

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 3⏎
You selected: -
Input integer number (a): 123456789012345678901234567890⏎
Input integer number (b): -987654321098765432109876543210⏎
(a) = 123456789012345678901234567890
(b) = -987654321098765432109876543210
(a) - (b) = 1111111110111111111011111111100

Multiplication

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 4⏎
You selected: *
Input integer number (a): 123456789012345678901234567890⏎
Input integer number (b): 987654321098765432109876543210⏎
(a) = 123456789012345678901234567890
(b) = 987654321098765432109876543210
(a) * (b) = 121932631137021795226185032733622923332237463801111263526900

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 4⏎
You selected: *
Input integer number (a): 123456789012345678901234567890⏎
Input integer number (b): -987654321098765432109876543210⏎
(a) = 123456789012345678901234567890
(b) = -987654321098765432109876543210
(a) * (b) = -121932631137021795226185032733622923332237463801111263526900

Division

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 5⏎
You selected: /
Input integer number (a): 987654321098765432109876543210⏎
Input integer number (b): 123456789012345678901234567890⏎
(a) = 987654321098765432109876543210
(b) = 123456789012345678901234567890
(a) / (b) = 8

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 5⏎
You selected: /
Input integer number (a): -987654321098765432109876543210⏎
Input integer number (b): 123456789012345678901234567890⏎
(a) = -987654321098765432109876543210
(b) = 123456789012345678901234567890
(a) / (b) = -8

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 5⏎
You selected: /
Input integer number (a): -987654321098765432109876543210⏎
Input integer number (b): -123456789012345678901234567890⏎
(a) = -987654321098765432109876543210
(b) = -123456789012345678901234567890
(a) / (b) = 8

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 5⏎
You selected: /
Input integer number (a): -123456789012345678901234567890⏎
Input integer number (b): 987654321098765432109876543210⏎
(a) = -123456789012345678901234567890
(b) = 987654321098765432109876543210
(a) / (b) = 0

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 5⏎
You selected: /
Input integer number (a): 123456789012345678901234567890⏎
Input integer number (b): -987654321098765432109876543210⏎
(a) = 123456789012345678901234567890
(b) = -987654321098765432109876543210
(a) / (b) = 0

Exceptions

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: +⏎
Invalid input: +

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 00000001⏎
Invalid input: 00000001

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 1⏎
You selected: display only
Input integer number (a): +_)(*(&#$)(*@()*@!⏎
Invalid input: +_)(*(&#$)(*@()*@!

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 1⏎
You selected: display only
Input integer number (a): 0.0⏎
Invalid input: 0.0

$ ./a.out
Big number calculator
1) display only
2) plus (+)
3) minus (-)
4) multiplication (*)
5) division (/)
Please select the operator: 4⏎
You selected: /
Input integer number (a): 123⏎
Input integer number (b): 0⏎
Invalid input: 0

Pseudo Code

#include <iostream>
#include <algorithm>
#include <cctype>
#include <vector>

using namespace std ;

int main()
{
    char buffer[10001]; // "+1" to store '\0'
    vector <int> a, b, n;
    int a_sign = 1, b_sign = 1 ;

    cin >> buffer ;
    // ToDo:逐字檢查,不合法顯示input後exit,合法則將(buffer[i] - '0')存入vector<int> n
    
    // isdigit():判斷是否為數字
    // reverse(.begin(), .end()):顛倒,將個位數移至第一位
    // .push_back():進位、填入數字
    // .pop_back():清除不必的'0'和'-'
    // .size():n的位數
    // 注意以上函數都需加上(),即便有的沒有input
    // 有加'.'在前面的,開頭需指定該vector,例如: n.size()

    switch (n[0])
    {
    case /* 1-5 */:
        /* 提示字串 */
        break;
    }
    
    for(int i=0; buffer[i] != '\0'; i++) buffer[i] = '\0' ; // 清空buffer

    cin >> buffer ;
    // ToDo:逐字檢查,不合法顯示input後exit,合法轉int存入vector<int> a

    cin >> buffer ;
    // ToDo:逐字檢查,不合法顯示input後exit,合法轉int存入vector<int> b

    cout << a << b ;

    // Initialization Done ---------------------------------------------
    
    if(n[0]==1) // "Display Only"
        return 0 ;
    else if(n[0]==2) // "+"
    {
        // ToDo
        return 0 ;
    }
    else if(n[0]==3) // "-"
    {
        // ToDo
        return 0 ;
    }
    else if(n[0]==4) // "*"
    {
        // ToDo
        return 0 ;
    }
    else if(n[0]==5) // "/"
    {
        // ToDo
        return 0 ;
    }
    
    // 乘法最簡單,加減相同作法,除法用減法

    return 0;
}

Reference:

Reference Code: TA

#include <iostream>
#include <vector>

using namespace std;

int main()
{
     char buffer[10001];
     vector<int> a, b, c;
     int n, a_sign = 1, b_sign = 1, c_sign = 1;
     bool zero_start = true;

     cout << "Big number calculator"
          << endl
          << "1) display only"
          << endl
          << "2) plus (+)"
          << endl
          << "3) minus (-)"
          << endl
          << "4) multiplication (*)"
          << endl
          << "5) division (/)"
          << endl
          << "Please select the operator: ";

     cin >> buffer;
     if (!isdigit(buffer[0]) || buffer[1] != '\0')
     {
          cout << "Invalid input: " << buffer << endl;
          return 0;
     }

     n = buffer[0]-'0' ;
     switch (n)
     {
     case 1:
          cout << "You selected: display only" << endl;
          break;
     case 2:
          cout << "You selected: +" << endl;
          break;
     case 3:
          cout << "You selected: -" << endl;
          break;
     case 4:
          cout << "You selected: *" << endl;
          break;
     case 5:
          cout << "You selected: /" << endl;
          break;
     default:
          cout << "Invalid input: " << buffer << endl;
          return 0;
     }
     
     for(int i=0; buffer[i] != '\0'; i++) buffer[i] = '\0' ;
     cout << "Input integer number (a): ";
     cin >> buffer;
     zero_start = true;

     for (int i = 0; buffer[i] != '\0'; i++)
     {
          if (!isdigit(buffer[i]))
          {
               if (i == 0 && buffer[i] == '-')
               {
                    a_sign = -1;
                    continue;
               }
               else
               {
                    cout << "Invalid input: " << buffer << endl;
                    return 0;
               }
          }

          if (buffer[i] == '0' && zero_start)
               continue;
          else
          {
               a.push_back((int)(buffer[i] - '0'));
               zero_start = false;
          }
     }
     if (a.empty())
     {
          a.push_back(0);
          a_sign = 0;
     }
     reverse(a.begin(), a.end());

     for(int i=0; buffer[i] != '\0'; i++) buffer[i] = '\0' ;
     cout << "Input integer number (b): ";
     cin >> buffer;
     zero_start = true;
     for (int i = 0; buffer[i] != '\0'; i++)
     {
          if (!isdigit(buffer[i]))
          {
               if (i == 0 && buffer[i] == '-')
               {
                    b_sign = -1;
                    continue;
               }
               else
               {
                    cout << "Invalid input: " << buffer << endl;
                    return 0;
               }
          }

          if (buffer[i] == '0' && zero_start)
               continue;
          else
          {
               b.push_back((int)(buffer[i] - '0'));
               zero_start = false;
          }
     }
     if (b.empty())
     {
          if (n == 5)
          {
               cout << "Invalid input: " << buffer << endl;
               return 0;
          }
          b.push_back(0);
          b_sign = 0;
     }
     reverse(b.begin(), b.end());

     cout << "(a) = " << (a_sign == -1 ? "-" : "");
     for (int i = a.size() - 1; i >= 0; i--)
          cout << a[i];
     cout << '\n'
          << "(b) = " << (b_sign == -1 ? "-" : "");
     for (int i = b.size() - 1; i >= 0; i--)
          cout << b[i];
     cout << endl;
     // Initialization Done

     int carry = 0;
     if (n == 1)
          return 0; // "Display only"
     // "Display only" Done

     else if (n == 2) // "+"
     {
          for (int i = 0; i < a.size() && i < b.size(); i++)
          {
               c.push_back((a[i] * a_sign + b[i] * b_sign + carry) % 10);
               carry = (a[i] * a_sign + b[i] * b_sign + carry) / 10;
          }
          if (a.size() > b.size())
          {
               for (int i = b.size(); i < a.size(); i++)
               {
                    c.push_back((a[i] * a_sign + carry) % 10);
                    carry = (a[i] * a_sign + carry) / 10;
               }
          }
          else
          {
               for (int i = a.size(); i < b.size(); i++)
               {
                    c.push_back((b[i] * b_sign + carry) % 10);
                    carry = (b[i] * b_sign + carry) / 10;
               }
          }
          c.push_back(carry);

          zero_start = true;
          for (int i = c.size() - 1; i >= 0; i--)
          {
               if (c[i] == 0 && zero_start)
                    c.pop_back();
               else
                    break;
          }
          if (c.empty())
               c.push_back(0);

          c_sign = (c[c.size() - 1] < 0 ? -1 : 1);

          for (int i = 0; i < c.size(); i++)
          {
               if (c_sign * c[i] < 0)
               {
                    c[i] += (10 * c_sign);
                    if (i + 1 < c.size())
                         c[i + 1] += (-1 * c_sign);
                    else
                         c.push_back(-1 * c_sign);
               }
               c[i] *= c_sign;
          }

          cout << "(a) + (b) = " << (c_sign < 0 ? "-" : "");
          for (int i = c.size() - 1; i >= 0; i--)
               cout << c[i];
          cout << endl;
          return 0;
     }
     // "+" Done

     else if (n == 3) // "-"
     {
          for (int i = 0; i < a.size() && i < b.size(); i++)
          {
               c.push_back((a[i] * a_sign - b[i] * b_sign + carry) % 10);
               carry = (a[i] * a_sign - b[i] * b_sign + carry) / 10;
          }
          if (a.size() > b.size())
          {
               for (int i = b.size(); i < a.size(); i++)
               {
                    c.push_back((a[i] * a_sign + carry) % 10);
                    carry = (a[i] * a_sign + carry) / 10;
               }
          }
          else
          {
               for (int i = a.size(); i < b.size(); i++)
               {
                    c.push_back((-b[i] * b_sign + carry) % 10);
                    carry = (-b[i] * b_sign + carry) / 10;
               }
          }
          c.push_back(carry);

          zero_start = true;
          for (int i = c.size() - 1; i >= 0; i--)
          {
               if (c[i] == 0 && zero_start)
                    c.pop_back();
               else
                    break;
          }
          if (c.empty())
               c.push_back(0);

          c_sign = (c[c.size() - 1] < 0 ? -1 : 1);

          for (int i = 0; i < c.size(); i++)
          {
               if (c_sign * c[i] < 0)
               {
                    c[i] += (10 * c_sign);
                    if (i + 1 < c.size())
                         c[i + 1] += (-1 * c_sign);
                    else
                         c.push_back(-1 * c_sign);
               }
               c[i] *= c_sign;
          }

          cout << "(a) - (b) = " << (c_sign < 0 ? "-" : "");
          for (int i = c.size() - 1; i >= 0; i--)
               cout << c[i];
          cout << endl;
          return 0;
     }
     // "-" Done

     else if (n == 4) // "*"
     {
          c_sign = a_sign * b_sign;
          for (int i = 0; i < b.size(); i++)
          {
               for (int j = 0; j < a.size(); j++)
               {
                    if (i + j >= c.size())
                         c.push_back(a[j] * b[i]);
                    else
                         c[i + j] += a[j] * b[i];
               }
          }
          for (int i = 0; i < c.size(); i++)
          {
               carry += c[i];
               c[i] = carry % 10;
               carry /= 10;
          }
          c.push_back(carry);

          zero_start = true;
          for (int i = c.size() - 1; i >= 0; i--)
          {
               if (c[i] == 0 && zero_start)
                    c.pop_back();
               else
                    break;
          }
          if (c.empty())
               c.push_back(0);

          cout << "(a) * (b) = " << (c_sign < 0 ? "-" : "");
          for (int i = c.size() - 1; i >= 0; i--)
               cout << c[i];
          cout << endl;
          return 0;
     }
     // "*" Done

     else if (n == 5) // "/"
     {
          c_sign = a_sign * b_sign;
          c.push_back(0) ;

          while (a.size() >= b.size())
          {
               for (int i = 0; i < b.size(); i++)
               {
                    carry += a[i] - b[i] + 10 ;
                    a[i] = carry % 10 ;
                    carry = carry / 10 - 1 ;
               }

               for (int i = b.size(); i < a.size(); i++)
               {
                    if( carry == 0 ) break ;
                    carry += a[i] + 10 ;
                    a[i] = carry % 10 ;
                    carry = carry / 10 - 1 ;
               }
               a.push_back(carry) ;

               zero_start = true;
               for (int i = a.size() - 1; i >= 0; i--)
               {
                    if (a[i] == 0 && zero_start)
                         a.pop_back();
                    else
                         break;
               }
               if (a.empty())
                    a.push_back(0);

               if ( a[a.size()-1] >= 0 ) c[0]++ ;
               else break ;
          }

          cout << "(a) / (b) = " << (c_sign < 0 ? "-" : "") << c[0] << endl ;
          return 0 ;
     }
     // "/" Done

     return 0;
}