Crushed by c++ assignment

Please help me understand how to solve this problem. I am totally lost and don't even know where to start.

Problem:

Create a class HugeInteger that uses a 40-element array of digits to store integers as large as 40 digits each. Provide member functions input, output, add and subtract. For comparing HugeInteger objects, provide functions isEqualTo, isNotEqualTo, isGreaterThan, isLessThan, isGreaterThanOrEqualTo and isLessThanOrEqualTo --- each of these is a "predicate" function that simply return true if the relationship is holds between the two HugeIntgers and returns false if the relationship does not hold. Also, provide a predicate function isZero. If you feel ambitious, provide member functions multiply, divide, and modulus.

RULES:
Must use the .h file, unmodified, below.
Provided .h file:

// Exercise 9.14 Solution: HugeInteger.h 
// HugeInteger class definition. 
#ifndef HUGEINTEGER_H 
#define HUGEINTEGER_H 
#include <array> 
#include <string>

class HugeInteger  
{ 
public: 
    HugeInteger( long = 0 ); // conversion constructor 
    HugeInteger( const std::string & ); // copy constructor 

// input 
    void input( const std::string & ); 
// output 
    void output() const; 

// addition operator; HugeInteger + HugeInteger 
HugeInteger add( const HugeInteger & ) const; 

// addition operator; HugeInteger + int 
HugeInteger add( int ) const;             

// addition operator;  
// HugeInteger + string that represents large integer value 

 HugeInteger add( const std::string & ) const;     

// subtraction operator; HugeInteger - HugeInteger 
HugeInteger subtract( const HugeInteger &  ) const;  

// subtraction operator; HugeInteger - int 
HugeInteger subtract( int ) const;  

// subtraction operator;  
// HugeInteger - string that represents large integer value 
HugeInteger subtract( const std::string & ) const;  

private: 
// 40 element array, initialized 
std::array< short, 40 > integer = { }; 
}; 

#endif

So if you had the following numbers

987459837459837457
792987349827346988

How would you add them together just using math/pen/paper?

When you can do that then you need to work out how to code that algorithm into this the implementation of this header

HugeInteger add( const HugeInteger & ) const;

1 Like

So my approach was to build the array integer by doing the following by building a for loop which cycles backward through an long int. I created two variables which, one would take the modulus of the long int and assign that number to array integer[i]. This gives me the last number off the long int. Next, I take the long int and /= 10 which knocks off the last digit. The for loop continues until the array is populated.

This is great. However, I dont't know how to implement this into the structure the teacher has set up for this assignment. I've tried to populate the private member array integer this way, however, I come up empty.

I'm totally blow away with the two constructors and how to use them to do this problem.

Here's how I tried to approach the problem by breaking down the long into individual elements in an array. I used a for loop and here is that for loop.

long longInt = 123456789; // value to put into array of shorts
array < short, 9 > integer = { }; // array of shorts
int theInt; // number to put into short element
for(int i = 8; i >=0; i--)
{
    theInt = longInt % 10; //gets last digit off longInt
    longInt /=10; //knocks last digit off longInt
    integer[i] = theInt;// puts value of theInt into array of shorts
}

So now I have an array of shorts. I can convert the into chars and have a c-string, which is what I think they .h file is suggesting that I do, but I'm not sure how this solves the problem.

@hardboiledphil

I would do this (assuming that we created arrays out of both the longs you listed and longArray[0] was the ones place):

bool remainder = false;

for(int i = 0; i < 18; i++)
    if(remainder == true);
    {
        longArray1[i] += 1;
    }

    if(longArray1[i] + longArray[i] > 10)
    {
        sumArray[i] = (longArray1[i] + longArray[i]) % 10;
        remainder = true;
    }
    else
    {
        sumArray[i] = (longArray1[i] + longArray[i];
        remainder = false;
    }
}

ok so you're righting an implementation for the first constructor - i.e. it populates itself from an int

The second constructor you need to be able to accept a string and end up with the same array you created from the first constructor (assuming you pass in the same number)

Once you've got these two constructors then think about how you can add them together, by iterating through BOTH arrays of ints and adding and carrying values as if you were doing it on paper.

1 Like

Add together as in create two HugeInteger instances each populated using the constructors and then you need to call the add operator on one of them

HugeInteger hugeInteger1 = ... HugeInteger("12345"); // one constructed from a string
HugeInteger hugeInteger2 = ... HugeInteger(new Long(98765)); // one constructed from an long

HugeInteger hugeInteger3 = hugeInteger1.add(hugeInteger2)

Seems like you've got an algorithm to try in ytour sample code for the implementation of the add operator :)

I'm a java dev and it's a while since I did any C++ but the idea is the same, just some different syntax perhaps...

1 Like

I have no idea... For me the exercise isn't detailed enough to figure out how I'm supposed to solve the problem.

I think I'm supposed to do something like (in my main.cpp file)

HugeInteger number1();
HugeIntger number2();

number1.input();
number2.input();

...

Basically, the constructors instantiate an empty array of shorts. The .input then calls a method where the person can put the numbers in... maybe???

No the first constructor accepts a long but defaults to 0 if none provided
The second constructor accepts a string.

So your first section of code would be the implementation of the first constructor. After calling new HugeInteger( with a long) it would have number1 as you've called it which is a HugeInteger with the internal array populated from the long that's you passed in.

1 Like

Part I:

HugeInteger number1(123456789);
HugeInteger numer2(987654321);

(allowing for syntatical differences between java and c++) I have now instantiated two HugeIntegers???

PartII:

Any idea why there is a constructor for a string?

They want you to able to do the following

HugeInteger number3("987654321");

Should be straightforward - just go through the characters of the string one by one, cast them to int as you store them in the array

The principle isn't really that hard, you just need to add numbers from the least significant to the most, while detecting and adding a carry to the following number. Subtraction is the same but reversed, you can check if your subtraction is less or equal to zero. Comparison can be done with checking of the length first (the number of digits), if they are equal then check every number from the most significant to the least, if you find any one is bigger - your job is done, you can stop. As for the array I suggest converting numbers to an array of characters, then subtracting 48 from each and every one and keeping them that way. 48 is 0 in ASCII, well you get the idea I hope, just turn them from ASCII to actual values, it will make your math simple.

1 Like

@DevBlox

Here's how I tried to approach the problem by breaking down the long into individual elements in an array. I used a for loop and here is that for loop.

long longInt = 123456789; // value to put into array of shorts
array < short, 9 > integer = { }; // array of shorts
int theInt; // number to put into short element
for(int i = 8; i >=0; i--)
{
    theInt = longInt % 10; //gets last digit off longInt
    longInt /=10; //knocks last digit off longInt
    integer[i] = theInt;// puts value of theInt into array of shorts
}

So now I have an array of shorts. I can convert the into chars and have a c-string, which is what I think they .h file is suggesting that I do, but I'm not sure how this solves the problem.

Addition Algorithm: (assuming I've created two arrays each 9 elements long from two HugeInteger Objects):

bool remainder = false;

for(int i = 0; i < 9; i++)
    if(remainder == true);
    {
        longArray1[i] += 1;
    }

    if(longArray1[i] + longArray[i] > 10)
    {
        sumArray[i] = (longArray1[i] + longArray[i]) % 10;
        remainder = true;
    }
    else
    {
        sumArray[i] = (longArray1[i] + longArray[i];
        remainder = false;
    }
}

That's my approach to the problem, but I can't figure out how to construct my objects yet.

@hardboiledphil
@DevBlox

constructor for HugeInteger: (creates an array of shorts);

HugeInteger::HugeInteger(long value)
{
    for(int i = 0; i < 9; i++)
    {
          integer[i] = value % 10;
          value /= 10;
    }

}

And can you prove that it does what you expect it to do?

Can you instantiate a HugeInteger using this constructor (using say 12345) and prove that the array contains [1] [2] [3] [4] [5] in your main class?

You might need to implement your output method so that you can get the value stored in the array out of the class. As it stands the array only exists as a private variable inside the class so nothing outside the class can get to it

cout << hugeInteger1.output() - not sure how you would pass it back though

One thing that looks strange is that a copy constructor (the second one) is usually where you pass in the same object type - in this case a HugeInteger. The constructor commented as a copy constructor in the original h file accepts a string - like the input method().

@hardboiledphil
@DevBlox

Here is my working solution to the problem. Thanks for responding and helping me get some momentum going to complete this exercise.

//headerfile (HugeInteger.h)

#ifndef HUGEINTEGER_H 
#define HUGEINTEGER_H

#include<iostream> 
#include<array> 
#include<string> 

using namespace std; 

class HugeInteger 
{ 
public: 
    HugeInteger(long = 0); 
    HugeInteger(const string &); 
    void output()const; 
    void input(const string &); 
    HugeInteger add(const HugeInteger &) const; 
    HugeInteger add(int) const; 
    HugeInteger add(const string &) const; 
    HugeInteger subtract(const HugeInteger &) const; 
    HugeInteger subtract(int) const; 
    HugeInteger subtract(const string &) const; 

private: 
    array < short, 40 > integer; 
}; 

#endif

//HugeInterger.cpp (Class implementation file)
#include <iostream>
#include <array>
#include <string>
#include "HugeInteger.h"

using namespace std;

HugeInteger::HugeInteger(long value)
{
    for (int i = 0; i < 40; i++)
    {
         integer[i] = 0;
    }
    for (int j = 39; value != 0 && j >= 0; j--)
    {
        integer[j] = static_cast < short >(value % 10);
        value /= 10;
    }
}

HugeInteger::HugeInteger(const string &string)
{
    input(string);
}

void HugeInteger::input(const string &val)
{
    for (int i = 0; i < 40; i++)
        integer[i] = 0;

    int length = val.size();
    int j;
    int k;

    for (j = 40 - length, k = 0; j < 40; j++, k++)
    {
        if (isdigit(val[k])) //checks to see if it's a digit
        integer[j] = val[k] - '0';
    }
}

void HugeInteger::output() const
{
    int i;
    for (i = 0; (integer[i] == 0) && (i < 40); i++)
        ; // skip leading zeroes
    if (i == 40)
        cout << 0;
    else
        for (; i < 40; i++)
            cout << integer[i];
  cout << endl;

}

HugeInteger HugeInteger::add(const HugeInteger &value) const
{
    int carry = 0;
    HugeInteger result;
    for (int i = 39; i >= 0; i--)
        {
            result.integer[i] = integer[i] + value.integer[i] + carry;
            if (integer[i] + value.integer[i] > 9)
            {
                 result.integer[i] %= 10;
                 carry = 1;
            }
            else
            {
                 carry = 0;
            }
        }
    return result;
}

HugeInteger HugeInteger::add(int num) const
{
     return add(HugeInteger(num));
}

 HugeInteger HugeInteger::add(const string &str) const
{
    HugeInteger val(str);
    HugeInteger result = this -> add(val);
    return result;
}

HugeInteger HugeInteger::subtract(const HugeInteger &value) const
{
    HugeInteger result;
    int carry = 0;
    for (int i = 39; i >= 0; i--)
    {
        int tempValue = integer[i];
        if (carry == 1)
        {
            tempValue -= 1;
        }
        if (integer[i] >= value.integer[i])
        {
             result.integer[i] = tempValue - value.integer[i];
             carry = 0;
        }
        else
        {
            result.integer[i] = (tempValue + 10) - value.integer[i];
            carry = 1;
        }
   }
return result;
}

HugeInteger HugeInteger::subtract(int num) const
{
return subtract(HugeInteger(num));
}

HugeInteger HugeInteger::subtract(const string &str) const
{
    HugeInteger val(str);
    HugeInteger result = this->subtract(val);

return result;
}

//Tester file
#include<iostream>
#include<string>
#include<array>
#include "HugeInteger.h"

using namespace std;

int main()
{
    HugeInteger num1(15);
    HugeInteger num2(20);
    HugeInteger num3 = num1.add(num2);
    HugeInteger num4("723");
    HugeInteger num5("321");
    HugeInteger num6 = num5.add(num4);
    HugeInteger num7 = num2.subtract(num1);
    HugeInteger num8 = num2.add(15);
    HugeInteger num9 = num2.subtract(15);
    HugeInteger num10 = num4.subtract(num5);

    cout << "num1 =";
    num1.output();
    cout << endl;

    cout << "num2 =";
    num2.output();

    cout << endl;

    cout << "num1 + num2 = ";
    num3.output();
    cout << endl;

    cout << "num2 - num1 = ";
    num7.output();

    cout << "num 4 = ";
    num4.output();
    cout << endl;

    cout << "num 5 = ";
    num5.output();

    cout << endl;

    cout << "num4 + num5 = ";
    num6.output();
    cout << endl;

    cout << "num2 + 15 = ";
    num8.output();
    cout << endl;

    cout << "num2 - 15 = ";
    num9.output();

    cout << endl;

    cout << "num 5 - 100 = ";
    num10.output();

     cout << endl;

    return 0;
}
1 Like

Looks good. Does it work? ;o)

It compiles and runs properly. Each case is tested in the tester.cpp file.

Now, I just have to do this part of the exerciser : "For comparing HugeInteger objects, provide functions isEqualTo, isNotEqualTo, isGreaterThan, isLessThan, isGreaterThanOrEqualTo and isLessThanOrEqualTo --- each of these is a "predicate" function that simply return true if the relationship is holds between the two HugeIntgers and returns false if the relationship does not hold."