A full adder simulation implementation in C++. It is implemented with a “adder queue” as part of the assignment prerequisites was adding 8 binary strings to a buffer for adding.
#include <iostream> #include <vector> #include <algorithm> //////////////////////////////////////////////////////////////////////////////// // Function Prototypes //////////////////////////////////////////////////////////////////////////////// std::string fullAdder(std::vector<std::vector*> adderIn); int userActivity(std::string stringBuff[9], std::vector<std::vector*> &adderInput); void fullAdderRecurs(std::vector<std::vector*> adderIn, bool &carry, std::string &outputString); void calculateSums(std::string stringBuff[9], std::vector<std::vector*> adderInput, std::vector<std::vector*> inputBuffer); bool andGate(bool P, bool Q); bool orGate(bool P, bool Q); bool xorGate(bool P, bool Q); //////////////////////////////////////////////////////////////////////////////// int main(void) { std::string stringBuff[9]; bool finish = false; std::vector<std::vector*> inputBuffer; std::vector<std::vector*> adderInput; if(userActivity(stringBuff, adderInput) == -1) { return -1; } calculateSums(stringBuff, adderInput, inputBuffer); // clean up for(int i = 0; i < adderInput.size(); i++) { delete adderInput[i]; } return 0; } //////////////////////////////////////////////////////////////////////////////// int userActivity(std::string stringBuff[9], std::vector<std::vector*> &adderInput) { for(int i = 0; i <= 7; i++) { std::cout << "\nPlease enter the " << (i+1) << " number now.\n"; // If it is odd, I know there is one behind it to compare against if((i & 0x1)) { std::cout << "This number will be added to " << stringBuff[i-1] << "\n"; } std::cin >> stringBuff[i]; // Check for one byte length of input std::cout << "Adding " << stringBuff[i] << " to adder queue\n"; // Create a new vector representing the input stream adderInput.push_back(new std::vector); /* Iterate through the string, turning 0's and 1's into true and false If a non binary symbol is detected, return -1 and exit */ for(auto it = stringBuff[i].begin(); it != stringBuff[i].end(); it++) { if((*(it)) == '0') { adderInput[i]->push_back(false); } else if((*(it)) == '1') { adderInput[i]->push_back(true); } else { std::cout << "Erroneous input - input that is" << " not a 0 or a 1 detected.\n"; return -1; } } } return 0; } //////////////////////////////////////////////////////////////////////////////// std::string fullAdder(std::vector<std::vector*> adderIn) { // Set the initial carry value to false bool carry = false; std::string returnString; // If there is a difference in string length, append 0's until same int dif = (adderIn[0]->size() - adderIn[1]->size()); // If it is less than 0, we know the first element is smaller if(dif < 0) { while(dif != 0) { adderIn[0]->insert(adderIn[0]->begin(), false); ++dif; } } // If it is greater than 0, we know the second element is smaller else if(dif > 0) { while(dif != 0) { adderIn[1]->insert(adderIn[1]->begin(), false); --dif; } } // Begin recursive adding fullAdderRecurs(adderIn, carry, returnString); // Big endian is the better of the two schemas, clearly... so std::reverse(returnString.begin(), returnString.end()); return returnString; } //////////////////////////////////////////////////////////////////////////////// void fullAdderRecurs(std::vector<std::vector*> adderIn, bool &carry, std::string &outputString) { // end is used instead of rbegin due to erase expecting an iterator // firstIt is A, secondIt is B auto firstIt = (adderIn[0]->end() - 1); auto secondIt = (adderIn[1]->end() - 1); bool S, buff; // Represents A XOR B buff = xorGate((*(firstIt)), (*(secondIt))); std::cout << "(A(" << (*(firstIt)) << ") XOR B(" << (*(secondIt)) << ") is " << buff << "\n"; std::cout << "(A(" << (*(firstIt)) << ") XOR B(" << (*(secondIt)) << ")) XOR Cin(" << carry << ") is "; // Represents XOR gate before S if(xorGate(carry,buff)) { std::cout << "true, adding 1 to output\n"; outputString += "1"; } else { std::cout << "false, adding 0 to output\n"; outputString += "0"; } // Reuse buff to represent the result of the upper AND gate buff = (carry && buff); std::cout << "(A(" << (*(firstIt)) << ") XOR B(" << (*(secondIt)) << ")) AND Cin(" << carry << ") is "; if(buff) { std::cout << "true\n"; } else { std::cout << "false\n"; } // Evaluate lower AND gate, and OR gate, to determine carry out std::cout << "Setting carry output to " << "((A(" << (*(firstIt)) << ") XOR B(" << (*(secondIt)) << ")) AND Cin(" << carry << ")) OR (A(" << (*(firstIt)) << ") AND B(" << (*(secondIt)) << "))" << " which is "; carry = orGate(buff, andGate((*(firstIt)), (*(secondIt)))); std::cout << carry << ".\n"; // Remove the two binary values that were added to advance through string adderIn[0]->erase(firstIt); adderIn[1]->erase(secondIt); // If there are no more bits left to iterate, end recursion if((adderIn[0]->size() == 0)) { // If carry bit is set, add 1 to string on the way out of recursion if(carry) { std::cout << "Carry bit set and no more bits left to add, " << "adding 1 to output\n"; outputString += "1"; } else { std::cout << "No more bits left to add\n"; } return; } // Recurse, and advance through the string due to the erases on ln161/162 else { fullAdderRecurs(adderIn, carry, outputString); } } //////////////////////////////////////////////////////////////////////////////// // Per assignment prerequisite, routines implementing the various gates bool andGate(bool P, bool Q) { return (P && Q); } //////////////////////////////////////////////////////////////////////////////// bool orGate(bool P, bool Q) { return (P || Q); } //////////////////////////////////////////////////////////////////////////////// bool xorGate(bool P, bool Q) { return (P ^ Q); } //////////////////////////////////////////////////////////////////////////////// void calculateSums(std::string stringBuff[9], std::vector<std::vector*> adderInput, std::vector<std::vector*> inputBuffer) { // Push the first two values onto a vector to pass into the fullAdder inputBuffer.push_back(adderInput[0]); inputBuffer.push_back(adderInput[1]); std::cout << "\n\n\nAdding " << stringBuff[0] << " and " << stringBuff[1] << "\n\n\n"; // Set the 8th stringBuff element equal to the sum of the first two elements stringBuff[8] = fullAdder(inputBuffer); std::cout << stringBuff[0] << " and " << stringBuff[1] << " equals " << stringBuff[8] << "\n\n\n";; // Clear the input buffer and prepare for next elements inputBuffer.clear(); // Repeat same as above with next two bit vectors inputBuffer.push_back(adderInput[2]); inputBuffer.push_back(adderInput[3]); std::cout << "\n\n\nAdding " << stringBuff[2] << " and " << stringBuff[3] << "\n\n\n"; stringBuff[8] = fullAdder(inputBuffer); std::cout << stringBuff[2] << " and " << stringBuff[3] << " equals " << stringBuff[8]; inputBuffer.clear(); inputBuffer.push_back(adderInput[4]); inputBuffer.push_back(adderInput[5]); std::cout << "\n\n\nAdding " << stringBuff[4] << " and " << stringBuff[5] << "\n\n\n"; stringBuff[8] = fullAdder(inputBuffer); std::cout << stringBuff[4] << " and " << stringBuff[5] << " equals " << stringBuff[8]; inputBuffer.clear(); inputBuffer.push_back(adderInput[6]); inputBuffer.push_back(adderInput[7]); std::cout << "\n\n\nAdding " << stringBuff[6] << " and " << stringBuff[7] << "\n\n\n"; stringBuff[8] = fullAdder(inputBuffer); std::cout << stringBuff[6] << " and " << stringBuff[7] << " equals " << stringBuff[8]; return; } ////////////////////////////////////////////////////////////////////////////////