Overview

You must extend the capabilities of your vtqulator program (from project 3) so that it can perform certain operations with integers that are arbitrarily large in magnitude. The size of these integers should (in principle) be limited only by the amount of memory in the machine. The only mathematical operations that need to support arbitrarily large magnitudes are addition (+), subtraction (-), multiplication (*), division (/), and exponentiation (^). You must also enhance your Qt-based GUI so that it supports multithreaded operation for these calculations.

Several libraries exist that support arbitrary-precision arithmetic (e.g., GMP). However, you are not allowed to use those libraries in completing this assignment. 

For this project, you are allowed to reuse or modify any of your own code from this semester, as well as any code that the instructors have provided to you during this semester. Do not borrow code from any other source without first seeking permission from an instructor. 

Here is the GitHub Invitation Link. Accept the GitHub invitation; wait until you get an email saying the import is complete; and then clone the git repository to your local machine. 

Large integers

Develop and test a VTmath code module that allows a C++ client to use integers that are limited in size only by the amount of memory in the computer. Your implementation must support both positive and negative integers for the operations +, -, *, and /. Your implementation of exponentiation (^) does not need to support negative values. For this module, you do not need to consider decimal points or floating-point values. 

What is a good way to represent very large integers? One approach might be for you to write code that uses 2’s-complement representation, to mimic what is done with standard integers by the CPU. For example, you could use a resizable linear data structure to represent 2’s-complement values with more and more bytes as needed. On the other hand, an alternative approach might be for you to represent all integers using BCD-encoded digits, also stored in a resizable linear data structure. An advantage of using BCD is that you can implement the arithmetic computations entirely in decimal form, essentially in the way that you would do those computations by hand using pencil and paper. Also, ultimately your code needs to convert integers to and from ASCII text, and BCD may provide some advantages for these input/output operations. 

Implement your code module using a C++ class named VTmath. See the starter code for more details. Your final solution must contain the interface and implementation for the VTmath class in files VTmath.h and VTmath.cpp, respectively. Do not change the signatures (prototypes) of the methods that are provided in the starter code, because those methods will be called directly by the instructor   tests at the autograder. However, you are allowed (even encouraged) to provide additional methods in the VTmath class. 

Notice that your VTmath implementation must be independent of your Qt-related code. The autograder will build a non-Qt program to test your VTmath module. 

Threading, and integration with vtqulator

For Project 4, update the Graphical User Interface that you developed for Project 3 by adding a QCheckBox that allows the user to toggle between the “Normal mode” (as specified for Project 3) and “VTmath mode”. The name of this QCheckBox widget should be set to “Mode_Normal_VTmath”, using setObjectName() as you did for Project 3. 

At initialization, your vtqulator program should go into Normal mode by default. When in Normal mode, your vtqulator program should satisfy all of the specifications that were given for Project 3. 

When the user toggles the QCheckBox to enter VTmath mode, vtqulator must start a new thread that performs VTmath calculations concurrently with vtqulator GUI operations. That new thread must terminate when the user toggles the QCheckBox to return to Normal mode. 

Your code must use the standard C++11 threading library to transfer user input and computed values between threads in a safe manner. 

It is suggested that your implementation should maintain separate processing stacks, one for Normal mode and one for VTmath mode. Whenever the user toggles the QCheckBox to enter or leave VTmath mode, vtqulator should clear all of these internal processing stack. 

When in VTmath mode, only the following input buttons will be enabled: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +/-, p, P, d, r, z, Z, n, f, space, backspace, return, +, -, *, /, and ^. All other buttons should be disabled by the use of a Qt method such as setEnabled(). 

When in VTmath mode, the user is allowed to enter numerical values containing any number of digits, and vtqulator must compute and display appropriate values of arbitrary size. (If some limit exists in the size of the integers, that limit should not be due to your implementations of VTmath or vtqulator.) 

Your vtqulator text window should keep the history of all inputs and outputs, even when toggling between Normal mode and VTmath mode. 

More requirements

Your implementation must allow assignments using integers or strings or other VTmath objects. Here are a few examples of valid assignments: 

VTmath m, n;
// assign a positive value
n = 1234;

n = "1234"; // same effect as previous statement
// assign a negative value
n = -1234;
n = "-1234";
n = "_1234";
m = n;
// same effect as previous statement
// same effect as previous statement

For all examples shown above, the method size() should report 4, which is the number of digits in each case. 

One reason for using assignment with strings is to accommodate large magnitudes. The C++ compiler will generate a warning or error if you enter a numerical constant into your source file that is too large for your numerical data type. For example, we are limited to about 18 digits for a long int.

long int i = 98765432109876543210;

error: integer constant is too large for its type

As indicated in the examples above, input strings may use “-” or “_” to indicate negative values. When your code produces an output string to represent an integer, however, negative values must be indicated by “-”. 

When producing an output string that represents an integer, your code must represent the value zero as "0". When reporting the number of digits in this value using size(), the correct answer is 1. 

Leading zeros or whitespace are not allowed in the output of your code. For example, "987" is correct but not "0987" or " 987". For negative values,"-987" is correct but not "-0987" or " -987" or "- 987". 

Your implementation should allow leading zeros as input, however, but should immediately remove the leading 0s in the internal representation. For example, your code should accept the following values as correct input strings: "0987" or "-0987" or "007" or "00". Your code will not be tested with strings that contain whitespace, such as " 987". 

Module specifications

- VTmath module: Your C++ code for VTmath must be in VTmath.h, VTmath.cpp.

- You must provide a Catch2 test file for VTmath in test_vtmath.cpp. These tests are completely independent of vtqulator, and this test file must not utilize anything related to Qt.

- Your C++ client code for vtqulator, with the main function, must be placed in file vtqulator_main.cpp.

- Interpreter module: As you did for Project 2 and Project 3, you may implement the computations for Normal mode in the files interpreter.h, interpreter.cpp.

- Layout module: As for Project 3, you may define and implement the layout of the GUI in the files vtqulator_gui.h, vtqulator_gui.cpp.
- OutputWindow module: Follow the same requirements as for Project 3.
- Testing module: This module must provide a set of tests covering its functionality with Qt Test. The associated file is test_vtqulator.cpp

Setting up the starter code in the reference environment

1. Create a working directory for your project somewhere on your computer. Open your command line terminal (e.g., PowerShell) and change to that directory.
2. Clone the
VTmath project after accepting the GitHub invitation (at the link given above):
% git clone https://github.com/VTECE3574/project4-USER.git
where USER is your GitHub username. You may have to enter your GitHub username and password. This step will create a git repository directory named project4-USER within your working directory.
3. Change into this repo directory (with the
cd command). You should see several source files.
where USER is your GitHub username. You may have to enter your GitHub username and password. This step will create a git repository directory named project4-USER within your working directory.
4. The starter code for Project 4 does not contain source files for
vtqulator. However, the new CMakeLists.txt file is correct for the VTmath module. (The files catch.hpp and Vagrantfile should be identical for Project 3 and Project 4, so you may want to copy your versions from Project 3.) Copy your Project 3 source files into this new repo directory, and then edit the new CMakeLists.txt as needed to accommodate both vtqulator and VTmath.
5. Run vagrant to set up the virtual machine.
% vagrant up
This step will take a several minutes to complete.
6. After the previous step completes, halt the VM using

% vagrant halt
This is how you stop the reference environment, but leave it ready to start up again.
7. Restart the VM using step 3 again. You should now see a graphical window.
8. Open a command line inside the VM window by right clicking and selecting Terminal emulator.
9. From inside the VM, see what directory you are in:

% pwd

You should be in the /home/vagrant directory, within the Ubuntu VM. This is the home directory for the default user setup by Vagrant. Typically, this is where you will create executable files. Feel free to remove the default subdirectories.

10. List the files in the host operating system that are shared with the Virtual Machine.

% ls /vagrant
You should see the files that are present the cloned repository on your host machine. Typically, this is where your source code will be.

11. Still working in the VM, build the starter code using cmake:

% cmake /vagrant
% make

(Eventually you should use STRICT mode, cmake -DSTRICT=True /vagrant, but at first you will need to be lenient until you do some code development.) Now you should be able to see 4 executable files in /home/vagrant. Just as you saw for Project 3, one of the executables is vtqulator for the GUI calculator, and another is test_vtqulator for testing using Qt Test. For VTmath, you should see test_vtmath for Catch unit testing, and run_vtmath for stand-alone (non-Qt) exercising of VTmath code. The file run_vtmath is provided only as an example to illustrate how you ca use VTmath with a separate client. 

12. Develop your code to implement all of the Project 4 specifications and associated tests. Eventually, use git to commit your updated source files to the local repository.

% git commit -m "Implement a GUI desk calculator for large integers"
13. Finally, synchronize your local repository with the corresponding one on GitHub:
% git push
You may have to enter your GitHub username and password.

Submission

To submit your work for grading:
1. Tag the
git commit that you wish to be considered for grading as “final”.
% git tag final
2. Push this change to GitHub
% git push origin final
If you decide that a later version should be considered as final, simply create and push a new tag, appending a monotonically increasing number to “final” using “-”. For example, final-2, final-3, etc. We encourage these tags in case they are needed to answer questions related to grading.

Your most recent submission to the Inginious autograder (up to the announced deadline) will determine your grade for this assignment. 

Grading

0 points: Code compiles in the reference environment with the STRICT setting
5 points: Code correctness for VTmath based on the student’s tests (proportional)
5 points: Code correctness for vtqulator based on the student’s tests (proportional)
5 points: Good coverage by student’s VTmath tests (using lcov in the reference environment)
5 points: Good coverage by student’s vtqulator tests (using lcov in the reference environment)
60 points: Code correctness based on the instructor’s tests (proportional)
10 points: No memory leaks (checked using valgrind in the reference environment)
5 points: Good coding style
5 points: Good development practices
Total: 100 points

Grading notes

- If your code does not compile/build in the reference environment, then the grade for this assignment will be 0 points.
- Coding style refers to good indentation and spacing, use of meaningful comments, good choice of variable names, and function lengths that are not excessive. A particular requirement is that you provide header comments near the top of each file that your create of modify extensively according the format stated in this course’s Grading Style Guidelines.
- Good development practices refers to regular, incremental, and well-packaged commits. For grading purposes, the (human) grader will look for at least 5 meaningful commits.