Hey guys so I'm having an issue with my program. Some information about my program it stores a const char* str converts it to int which is in ascii then it runs a test on the number and converts it back to a string. Then it will also add these numbers up for some reason I am getting passed my first two tests but when I work on the addition one I'm getting the wrong negative number I will post my code below, test 3 is the one giving the wrong output. When I print it out I see the numbers there but something is happening maybe where the -3 appears before the number for example 937-300000000 etc. If you could help that would be greatly appreciated, I've been staring at it for awhile maybe another input will help. Thanks in advanced.

#include <iostream>
using namespace std;

class BigInt
{
public:

    BigInt() {}
    BigInt(const char*);
    BigInt add(const BigInt&);
    BigInt operator+(const BigInt&);
    string convertToString();

private:
    static const int NUM_DIGITS = 100;
    int numArr[NUM_DIGITS];
    void tensComplement();
};

//A constructor which accepts a C string
BigInt::BigInt(const char* str) {
    // TODO: CONVERT C-STRING TO BIGINT
    int len = strlen(str) - 1;
    int zero = NUM_DIGITS - 1;
    for (int i = 0; i < NUM_DIGITS; i++){
        numArr[i] = 48;
    }
    for (int i = len; i >= 0; i--){
        numArr[zero] = str[i];
        zero--;
    }
}

BigInt BigInt::add(const BigInt& rightOperand) {
    BigInt objToReturn("0");
    // TODO: ADD LOGIC HERE
    int carry = 0;
    for (int i = 100; i > 0; i--){
        int left = this->numArr[i] - 48;
        int right = rightOperand.numArr[i] - 48;
        int total = left + right;
        if (total > 9){
            carry = 1;
        }else{
            carry = 0;
        }
        total += carry;
        total = total % 10;

        objToReturn.numArr[i] = total + 48;
    }
    //num1 is the this object
    cout << this->numArr[NUM_DIGITS];

    //num2 is the rightOperand object
    cout << rightOperand.numArr[NUM_DIGITS];

    return objToReturn;
}

BigInt BigInt::operator+(const BigInt& rightOperand){
    return add(rightOperand);
}

string BigInt::convertToString(){
    // TODO: VALUE IN numArr CONVERTED TO STRING
    int count = 0;
    string str;
    if(numArr[0] == 57){
        tensComplement();
    }
    cout << "Output: " << str;
    for (int i = 0; i < NUM_DIGITS; i++){
        if(numArr[i] == 48 && count == 0){

        }else{
            str.push_back(numArr[i]);
            count++;
        }
    }
    cout << str << endl;
    return str;
}

void BigInt::tensComplement(){
    // TODO: TENS COMPLEMENT OF THIS NUMBER
    for (int i = 0; i <= 100; i++) {
        numArr[i] = 9 - numArr[i];
    }
    numArr[NUM_DIGITS] += 1;
    for(int i = NUM_DIGITS; i >= 1; i--){
        if(numArr[i] == 10){
            numArr[i] = 0;
            numArr[i - 1] += 1;
        }
    }
    if(numArr[0] == 1){
        numArr[0] = 9;
    }
}


//This helps with testing.
bool checkTest(string testName, string whatItShouldBe, string whatItIs) {

    if (whatItShouldBe == whatItIs) {
        cout << "Passed " << testName << " last digit was: " << whatItIs.at(whatItIs.length()-1) << endl;
        return true;
    }
    else {
        if (whatItShouldBe == "") {
            cout << "**Failed test " << testName << " ** " << endl << "   Output was "<< whatItIs << endl << "   Output should have been blank. " << endl;
        } else {
            cout << "**Failed test " << testName << " ** " << endl << "   Output was "<< whatItIs << endl << "   Output should have been " << whatItShouldBe << endl;
        }
        return false;
    }
}

int main()
{
    BigInt result;

    BigInt num1("999");
    BigInt num2("4873");
    BigInt num3("-739");
    BigInt num4("-9871");

    // Test 1
    checkTest("Test 1", "999", num1.convertToString());

    // Test 2
    checkTest("Test 2", "-739", num3.convertToString());
    //Test some addition problems

    // Test 3, negative + negative
    result = num3.add(num4);
    checkTest("Test 3", "-10610", result.convertToString());
    return 0;
}

Edited 2 Years Ago by Sasquadge

The problem is your representation of the data (which of course then effects all your code). You have represented the data in the way you think about it as a human not in a way that makes it convienient to process has a computer.

BTW at least at line 26 if you mean the character '0' use the character '0' not the integer 48 because not all environements use the same execution character set and in some character sets the character '0' has a value other than 48.

So for demonstration purposes I am going to assume that NUM_DIGITS is 10

For -739 you hold the string "000000-739"
For -9871 tou hold the string "00000-9871"

You then add them character by character in reverse order and you add the carry at the wrong place, the carry is supposed to be carried over to the next column, you calculate the carry at line 42 and use it at line 47 but you should calculate it at line 42 and use it at line 41 and initialise it to 0 which you do do.

so
9 + 1 = result + carry
3 + 7 = result + carry
7 + 8 = result + carry
7 + 3 = result + carry
('-' - 48) + 9 = result + carry
0 + ('-' - 48) = result + carry
0 + 0 = result + carry
0 + 0 = result + carry
etc.

See the issue, because you have included a non-digit in your digit string and then not looked out for it you have created a logic issue.

I would separate out the sign from the digit string, I would also use a std::vector not a char array, then the digit string can be as long as is necessary and also not longer than necessary. Since I am handling digit strings that might be different lengths I would reverse the order I store the digits in, i.e. units at index 0, tens at index 1, 100s at index 2 etc. some that the same column is at the same index even in digit strings of differing lengths (you will have to reverse the string for output).

You will need to implement subtraction before you can complete your implementation of addition, they are complimentary. Otherwise you can only handle addition of values of the same sign i.e. 5 + -2 == 5 - 2. You use the relative signs of the values to work out whether you are subtracting or adding your digit strings for both add and subtract and then call an internal helper function to perform the digit string addition or digit string subtraction.

I would imlement a function to normalise the digit string, my normalised form would be to have no leading zeros.

I have no idea what you tensComplement method is meant to do, what it actually does or what its intended purpose is but to me it appears to be entirely superfluous and probably and error in the design logic somewhere.

Additionally when implementing maths operators +, -, *, / etc. then generally you get a slight more efficient implementation if you implement the assignment version of ther operator and then implement the operator in terms of the assignment version i.e.

class Example
{
// Constructors etc.

  const Example& operator+=(const Example& op)
  {
    // implementation here
    return *this;
  }

  Example operator+(const Example& op)
  {
    Example result(*this);
    result += op;
    return result;
  }

}

You can implement += in terms of + but you end up doing at least 1 extra copy operation.

Similarly if you implement != and < then you can implement all the other comparisons in terms of these 2.

The point of the project is to be able to store base-10 numbers with 100 digits or more and then add these or subtract them. The tensComplement is for those numbers with 100 digits. Basically if a number is negative I need to store in into the tens complement form if that makes sense. I'm kind of confused with this project but I'm trying to get it working somehow haha. here are more test outputs I will be testing should of kept them in

    BigInt num1("999");
    BigInt num2("4873");
    BigInt num3("-739");
    BigInt num4("-9871");
    BigInt num5("123456789012345678901234567890");
    BigInt num6("5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555556");
    BigInt num7("6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667");
    BigInt num8("1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112");
    BigInt num9("-1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
    BigInt num10("-30");
    BigInt num11("4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444443");
    BigInt num12("-8999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999");
    BigInt num13("-4444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444443");
    BigInt num14("-1");
    BigInt num15("1");

Edited 2 Years Ago by Sasquadge

Sorry I read this just before home time and didn't have time to reply. I have read up on 10s complement, which appears to be a way to simplify dealing with negatives during addition/subtraction. Fantastic, but you only call it while converting the number to a string.

It sounds like the sort of function that you should call just before doing addition involving negatives or subtraction.

You cannot just take the 10s completement of your initialisation value because you cannot tell the difference between 931, a positive number, and 931, the 3 digit 10s complement of -69 which means that when you do 931 + 931 you can't tell if the result is 1862 (adding 2 positive numbers), 862 (adding a positive and a negative number) or -138 (adding 2 negative numbers requiring the extra step of doing the 10s complement again to convert 862 to -138).

You need to know if the original number was positive or negative and there is no facility for that in you code.

You say you need to be able to cope with 100 digits or more but your code compes with a maximum of 100 digits, I still think a vector is going to help you here to allow you to store any number of digits, when doing addition/subtraction you can always temporarily pad the number with the smaller number of digits to the longer one.

Given all that I probably would not store the number in 10s complement if negative, however that doesn't mean that you can't or shouldn't, however you don't because to do that would involve a tensComplement call in your constructor. But however you store your digit string you definately need to store if it was negative originally.

However even given all of that when using 10s complement you need to know whether you expect the result to be positive or negative, for example if I tell you the result of an addition was 953 you can't tell if I mean 953 or its 10s complement -47. If I tell you the 2 numbers I added, 131 and 822 you still can't tell. You can only tell when I tell you that 822 was actually the 10s complement of -178. You have to work out the logic and make sure you can tell the difference between 131 - 178, 131 + 822, -869 - 178 and -869 + 822.

I would also be inclined implement the assignment operator rather than rely on the compiler provided default.

This article has been dead for over six months. Start a new discussion instead.