0

I have input such as:

10000000000000-1= and AAAAABBBBBCCCCCDDDDDEEEEEFFFFF-ABCDEF0123456789ABCDEF=

I need to convert the hexadecimal strings digit by digit into decimal and keep track if I need to borrow. I'm not sure how to adjust the value of operand 1 when a borrow occurs. Such as in the first line when you have to borrow 13 times. Currently, I have

#include <iostream>
#include <fstream>
using namespace std;

string decimalToHex(int);
void subtraction(string, string)
int hexadecimalToDecimal(char hexVal);
int fullSubtractor(int tempOp1, int tempOp2)

int main()
{
    ifstream myFile;
    string l1, l2, l3, l4, l5, l6, l7, l8; //lines
    string l1op1, l1op2, l2op1, l2op2, l3op1, l3op2, l4op1, l4op2, l5op1, l5op2, l6op1, l6op2, l7op1, l7op2, l8op1, l8op2; //parsed operators
    myFile.open("data.txt");
    if (myFile.is_open()) //check if file opened
    {
        cout << "File opened successfully. " << endl;
    }
    else
    {
        cerr << "File failed to open." << endl;
        return 1;
    }
    while (!myFile.eof())
    {
        myFile >> l6 >> l7; //read in line by line
    }
    l6op1 = l6.substr(0, l6.find("-"));
    l6op2 = l6.substr(l6.find("-") + 1);
    l6op2 = l6op2.substr(0, l6op2.length() - 1);
    std::string l6op2_zeros = std::string((l6op1.length()) - l6op2.length(), '0') + l6op2;
    cout << l6; // << subtraction(l6op1, l6op2_zeros) << endl;
    subtraction(l6op1, l6op2_zeros);
    cout << endl;

    l7op1 = l7.substr(0, l7.find("-"));
    l7op2 = l7.substr(l7.find("-") + 1);
    l7op2 = l7op2.substr(0, l7op2.length() - 1);
    std::string l7op2_zeros = std::string((l7op1.length()) - l7op2.length(), '0') + l7op2; //appends zeros to front of second operand to make it same length as operand 1
    cout << l7; // << subtraction(l7op1, l7op2) << endl;
    subtraction(l7op1, l7op2_zeros);
    cout << endl;
    myFile.close();
    return 0;
}
int fullSubtractor(int tempOp1, int tempOp2)
{
    static int borrow;
    int result = 0;

    if ((tempOp1 < tempOp2) || ((tempOp1 == 0) && (borrow == 1)))
    {
        tempOp1 += 16;
        result = tempOp1 - borrow - tempOp2;
        borrow = 1;
    }
    else
    {
        result = tempOp1 - tempOp2;
        borrow = 0;
    }
    return result;
}
void subtraction(string op1, string op2)
{
    string result;
    int tempDifference = 0, tempHex = 0;
    int j = op2.length() - 1;

    for (int i = op1.length() - 1; i >= 0; i--)
    {
        int temp1 = hexadecimalToDecimal(op1[i]);
        int temp2 = hexadecimalToDecimal(op2[j]);
        tempHex = fullSubtractor(temp1, temp2);
        result = decimalToHex(tempHex) + result;
        cout << result << " ";
        j--;
    }
    cout << result << endl;
    //return result;
}
int hexadecimalToDecimal(char hexVal)
{
    int base = 1;
    int dec_val = 0;

    if (hexVal >= '0' && hexVal <= '9')
    {
        dec_val += (hexVal - 48) * base;
        base *= 16;
    }
    else if (hexVal >= 'A' && hexVal <= 'F')
    {
        dec_val += (hexVal - 55) * base;

        // incrementing base by power 
        base *= 16;
    }
    return dec_val;
}
string decimalToHex(int decNum)
{
    stringstream ss;
    ss << hex << decNum;
    string hexNum(ss.str());
    //cout << hexNum << endl;
    return hexNum;
}
Tobias Wollgam
  • 671
  • 2
  • 7
  • 23
Tyler
  • 13
  • 3
  • I suggest you just test the function that takes two hex strings, subtracts them, and returns the result. The `main` function you're showing us does things with `-` characters and other irrelevant things. – PaulMcKenzie Nov 18 '19 at 18:30
  • I was just trying to create a reproducible example by including main. The function works except when it needs to borrow from more than one digit over like 100-1. Subtraction just converts digit by digit to decimal then calls fullSubtractor which increments by 16 if operand 1 is less & updates borrow then subtraction converts the answer back to hex and loops until end of operand – Tyler Nov 18 '19 at 18:49
  • Try putting leading 0's in the shorter string so that it is equal in length to the longer string. Then it becomes `100 - 001` and the issue of more than one digit becomes a moot point. – PaulMcKenzie Nov 18 '19 at 18:53
  • I do that in main e.g. ```std::string l6op2_zeros = std::string((l6op1.length()) - l6op2.length(), '0') + l6op2;``` – Tyler Nov 18 '19 at 18:54
  • 1
    Then how would you do this with pencil and paper? You will always be subtracting one digit at a time, so I don't know what issue you're speaking of. Make it simple -- how would you do this if the base was 10 instead of 16? That very same set of steps would be done, except that a 16 is borrowed instead of 10. – PaulMcKenzie Nov 18 '19 at 18:56
  • I agree and I'm able to work it out on paper. It's something I'm missing in fullSubtractor. AAAAABBBBBCCCCCDDDDDEEEEEFFFFF-ABCDEF0123456789ABCDEF= aaaaabbb**0ff**eddccba988765443210 but I'm getting aaaaabbb**100**eddccba988765443210 – Tyler Nov 18 '19 at 19:04
  • 1
    Well, at the point where the answer is wrong, debug from there (using your debugger) and see where your code goes in a different direction than what you expected. – PaulMcKenzie Nov 18 '19 at 19:05
  • It's definitely caused by how I implement the borrow. Just a matter of figuring out a different approach. – Tyler Nov 18 '19 at 19:25
  • Recommended reading: [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons). Come to think of it, that read logic just doesn't seem right. I think the math should be inside the loop. – user4581301 Nov 18 '19 at 19:25

0 Answers0