HugeInt class/data type

Apr 5, 2010 at 8:07pm
i am doing a project at school but i am having problems that even my instructor can't help me figure out.

exercise:
(HugeInteger class) create a class HugeInteger that uses a 40-element array of digits to store a integer as large as 40 digits. Provide member functions input,output,add,andsubtract. For comparing HugeInteger object, provide functions isEqualto, isNotEqualTo, isGreaterThan, isLessThan isGreaterThanOrEqualTo, and isLessThanOrEqualTo-each of these is a "predicate" function that simply returns true if the relationship holds between the two HugeIntegers and returns false if the relationship does not hold. Also provide a predicate isZero. if you feel ambitious, provide member functions multiply, devide, and modulus.

HugeInt.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

class HugeInt{
private:
        //global variables
        int number[40];//holds the number in separate indexes
        int count;//keeps count of how many digits the inputed number is
public:
       void input(){// takes in the number
            string temp,x;
            cout <<"Please enter a number no more than 40 digits long: "<<endl;
            cin >>temp;//get string of digits
            count=temp.size();//initalize count
            for(int i=0;i<count;i++){
                x=temp[i];
                istringstream buffer(x);
                buffer >> number[i];//convert string digit to int
                }//end for loop
            }//end input()
            
       void output(){//displays the number
            for(int i=0;i<count;i++){
                cout <<number[i];//print each number 1 by 1
                }//end for
            }//end output()
            
       //HugeInt operator +(*HugeInt,*HugeInt){//adds the 2 HugeInts
               
       
//       HugeInt operator -(*HugeInt,*HugeInt);
       
       bool operator==(const HugeInt *b){
            if(count != b->count){
               return false;
               }else{
               for(int i=count;i>=0;i--){
                   if(number[i]!=b->number[i]){
                      return false;
                      }//end nested if
                   }//end for
               }//end if else
            return true;
            }//end operator ==
       /*     
       bool operator!=(HugeInt *a,HugeInt *b){
            if(a->count == b->count){
               return false;
               }else{
               for(int i=a->count;i>=0;i--){
                   if(a->number[i]==b->number[i]){
                      return false;
                      }//end nested if
                   }//end for
               }//end if else
            return true;
            }//end operator !=
            
       bool operator>(HugeInt *a,HugeInt *b){
            if(a->count > b->count){
               return true;
               }else{
               string a1,b2;
               for(int i=0;i<=a->count;i++){
                   a1+=a->number[i];
                   }//end for loop
               for(int i=0;i<=b->count;i++){
                   b2+=b->number[i];
                   }//end for loop
               if(a1 > b2){
                  return true;
                  }//end nested if
               }//end if
            return false;
            }//end operator >
            
       bool operator<(HugeInt *a,HugeInt *b){
            if(a->count < b->count){
               return true;
               }else{
               string a1,b2;
               for(int i=0;i<=a->count;i++){
                   a1+=a->number[i];
                   }//end for loop
               for(int i=0;i<=b->count;i++){
                   b2+=b->number[i];
                   }//end for loop
               if(a1 < b2){
                  return true;
                  }//end nested if
               }//end if
            return false;
            }//end operator <
       
       bool operator >=(HugeInt *a,HugeInt *b){
            if(*a > *b || *a == *b){
               return true;
               }//end if
            return false; 
            }//end operator >=
       
       bool operator <=(HugeInt *a,HugeInt *b){
            if(*a < *b || *a == *b){
               return true;
               }//end if
            return false;
            }//end operator <=
*/
};//endl class 


HugeIntTesterMain.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <cstdlib>
#include <iostream>
#include "HugeInt.h"

using namespace std;

void menu(){
     HugeInt num1;//number 1
     
   
HugeInt num2;//number 2
HugeInt answer;



     int var1=0;//menu control variable
     while(var1<10){
           system("CLS");
           cout <<"Main Menu"<<endl;
           cout <<"1.Input 1st number"<<endl;
           cout <<"2.Input 2nd number"<<endl;
           cout <<"3.Display all numbers"<<endl;
           cout <<"4.Equal to?"<<endl;
           cout <<"5.Not Equal to?"<<endl;
           cout <<"6.Greater than?"<<endl;
           cout <<"7.Less than?"<<endl;
           cout <<"8.Greater than or Equal to?"<<endl;
           cout <<"9.Less than or Equal to?"<<endl;
           cout <<"10.Exit"<<endl;
           cin >>var1;
           
          
            
           system("CLS");
           switch(var1){
                  case 1:num1.input();break;
                  case 2:num2.input();break;
                   
                  case 3:
                       cout <<"Number 1: ";
                       num1.output();
                       cout <<endl;
                       cout <<"Number 2: ";
                       num2.output();
                       cout <<endl;
                       system("PAUSE");
                       break;
                  case 4:
                       cout <<"Is number 1 = number 2?"<<endl;
                       if(num1==num2){
                          cout <<"True"<<endl;
                          }else{
                          cout <<"False"<<endl;
                          }//end if
                       system("pause");
                       break; 
                  /*
                  case 5:
                       cout <<"Is number 1 != number 2?"<<endl;
                       if(num1 != num2){
                          cout <<"True"<<endl;
                          }else{
                          cout <<"False"<<endl;
                          }//end if
                       system("pause");
                       break;
                  case 6:
                       cout <<"Is number 1 > number 2?"<<endl;
                       if(num1 > num2){
                          cout <<"True"<<endl;
                          }else{
                          cout <<"False"<<endl;
                          }//end if
                       system("pause");
                       break;
                  case 7:
                       cout <<"Is number 1 < number 2?"<<endl;
                       if(num1 < num2){
                          cout <<"True"<<endl;
                          }else{
                          cout <<"False"<<endl;
                          }//end if
                       system("pause");
                       break;
                  case 8:
                       cout <<"Is number 1 >= number 2?"<<endl;
                       if(num1 >= num2){
                          cout <<"True"<<endl;
                          }else{
                          cout <<"False"<<endl;
                          }//end if
                       system("pause");
                       break;
                  case 9:
                       cout <<"Is number 1 <= number 2?"<<endl;
                       if(num1 <= num2){
                          cout <<"True"<<endl;
                          }else{
                          cout <<"False"<<endl;
                          }//end if
                       system("pause");
                       break;*/
                  }//end switch
           }//end while loop
} //end menu()
int main()
{
    menu();   
    return EXIT_SUCCESS;
}


quite a bit of the code is commented out since we have been debugging it.
if anybody has any ideas please post back.
i have been working on this project for about 2 and half weeks(mostly debugging)
Apr 5, 2010 at 8:26pm
What's your question?
Apr 5, 2010 at 10:49pm
The issues are in your header file. Hint no matter what the teacher says, commenting out code so that the error goes away is not the only trouble shooting method. This is a trickey one I will be back to you if I find anything. P.S. thanks for the puzzle.
Apr 5, 2010 at 10:51pm
 
bool operator==( const HugeInt& rhs ) const;


is the correct declaration. Your declaration requires the rhs to be a pointer, so you would have to
write:

 
if( num1 == &num2 )


secondly, you have multiple errors here:

 
for(int i=count;i>=0;i--){


you read the integer into elements 0, 1, 2, 3, etc, where number[0] is the most significant digit, but
you are comparing elements 40, 39, 38, etc.

Apr 6, 2010 at 2:31am
Sorry, I started this response earlier (after helios) but had to do some stuff...

This is an "AAAHHH HELP!" question.

Lines 1 and 109

You don't need C stuff in your C++ program. Just return 0;. (Personally, I like the EXIT_SUCCESS macro, but it is really wholly redundant. A successful C or C++ program almost always returns zero, and that much is understood by C and C++ programmers everywhere -- to the point that if your program does not return zero you have to explain why.)

Line 9

They are not global variables. They are the data encapsulated by your class. As they are (correctly) listed as private fields, only your class's methods may access them.

Line 10

This should be an array of char -- you don't need more space per digit than that.

Before you get too much further, you need to decide explicitly how your number is stored in the array. The first thing to consider is that your array is supposed to be an array of digits - that is: 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9.

Here is my recommendation: store it as an array of integer values. That is, don't store it as the character values '0'..'9', but as the actual numbers 0..9.

1
2
char a_number    =  4;
char a_character = '4';

See the difference? The choice between characters and integers affects how easy it is to do other operations on the number. If you choose characters, then every time you wish to add, subtract, multiply, etc then you must convert each digit between its character value and its integer meaning. If you choose integers, then the only time you need to do the conversion is when reading or writing the number.

At the moment, you are treating it both ways. Remember, the character '2' is a number, but it is not the number 2.

The next consideration is how the number is arrayed:
  ■ most significant digit to least (reading order) - 123 is stored as ['1', '2', '3']
  ■ least significant digit to most - 123 is stored as ['3', '2', '1']

I recommend you keep your digits in the second order. This makes your operations that much easier, since you don't have to line-up the powers between two different HugeInts - it is already done for you. The one's place is always at index zero. The ten's place is always at index one. Etc.

The final thing to remember is that an integer number may be negative. If we restrict our array to positive values (a reasonable thing to do to keep the code simple), then we need an extra field to track the sign.

With all that, I would write my private section as:
8
9
10
11
private:
        char digits[40];  // the digits of the number, least significant to most
        int  count;       // number of digits in the number
        bool negative;    // the sign of the number 


Methods

Your instructor has not told you to overload the C++ binary operators for HugeInts. Instead, you have been told to create specifically-named methods.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public:
        // I/O. Make your life easy now and require a stream to operate over as argument
        void input( istream& ins );
        void output( ostream& outs );

        // Addition
        void add( const HugeInt& that );
        void subtract( const HugeInt& that );

        // Comparisons
        bool isEqualto( const HugeInt& that ) const;
        bool isNotEqualTo( const HugeInt& that ) const;
        bool isGreaterThan( const HugeInt& that ) const;
        bool isLessThan( const HugeInt& that ) const;
        bool isGreaterThanOrEqualTo( const HugeInt& that ) const;
        bool isLessThanOrEqualTo( const HugeInt& that ) const;

        // Additional predicate
        bool isZero() const;

        // Extra credit: Multiplication
        void multiply( const HugeInt& that );
        void divide( const HugeInt& that );  // (not "devide")
        void modulo( const HugeInt& that );  // (not "modulus") 


Notice that that additive and multiplicative methods modify the HugeInt. In C++, essentially, the following operations on a HugeInt are the same:
  ■ this.add( that );
  ■ this += that;

The comparative methods, in contrast, do not modify the HugeInt. Hence, they are const methods.

I have a return type of void on your arithmetic operations, but if I were writing this assignment myself I would return a reference to *this. This is a personal preference, however:
17
18
        // Addition
        HugeInt& add( const HugeInt& that );


I would also recommend you have an assign() method, that copies the value of another HugeInt to this one.

Now in your CPP file, you can implement the methods you defined in the class above (listed in a HPP file).

At this point, you need to decide how to handle things like overflow.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
HugeInt& HugeInt::add( const HugeInt& that )
{
        if (negative != that.negative)
        {
                ...  // Think about how to handle this using what other methods there are.
        }
        else
        {
                int  index = 0;
                char carry = 0;
                ... // Loop through each digit in this.digits[] and that.digits[] and add everything
        }
        return *this;
}

bool HugeInt::isEqual( const HugeInt& that ) const
{
        if (count != that.count)
                return false;

        if (negative != that.negative)
                return false;

        for (int n = 0; n < count; n++)
                if (digits[n] != that.digits[n])
                        return false;

        return true;
}

Well, that's enough for now. Hope this helps.
Apr 6, 2010 at 12:07pm
Before I forget again, writing an input() function is tricky. One, you should NOT have any couts in an input operation. Also, only use the stream given to you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
istream& HugeInt::input( istream& ins )
{
        // Start with zero digits
        count = 0;

        // Skip any leading whitespace
        ins >> skipws;

        // Accept negative numbers
        if (ins.peek() == '-')
        {
                ins.get();
                negative = true;
        }
        else    negative = false;

        // While there is a digit to read... (#include <cctype> somewhere above)
        while (isdigit( ins.peek() ))
        {
                // Fail if there are more than 40 digits
                if (count == 40)
                {
                        ins.setstate( ios::failbit );
                        return ins;
                }
                // Assign the digit's value to the next available spot
                digits[ count ] = ins.get() - '0';
                count++;
        }
        // Since we read the digits from most significant to least, we
        // now need to reverse their order so that they are least
        // significant to most. It is easy enough to do yourself, but
        // here we just use the STL reverse() algorithm.
        // (#include <algorithm> somewhere above)
        reverse( digits, digits + count );
        return ins;
}

The reason I wrote the function this way is so that you can implement an extraction operator with it:

1
2
3
4
istream& operator >> ( istream& ins, HugeInt& hugeint )
{
        return hugeint.input( ins );
}

Now when you write your code, you can get input either way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <limits>
#include "hugeint.hpp"

using namespace std;

int main()
{
        HugeInt n;
        cout << "Please enter a very large integer number (maximum 40 digits)\n> ";

        // Method one (chose either this one or method two)
        n.input( cin );

        // Method two (chose either this one or method one)
        cin >> n;

        if (!cin)
        {
                cout << "Hey, that was either not a number or it was more than 40 digits!\n";
                return 1;
        }

        // (Eat the newline waiting at the end of the user's input)
        cin.ignore( numeric_limits <streamsize> ::max(), '\n' );

        cout << "Good job! You entered the number:\n  ";

        // Method one
        n.output( cout );

        // Method two
        cout << n;

        cout << endl;

        cout << "Press ENTER to quit..." << flush;
        cin.ignore( numeric_limits <streamsize> ::max(), '\n' );
        return 0;
}

Your output() function should work similarly (it is just much easier because all you have to do is output a minus sign if the number is negative, followed by digits[ count-1 ] + '0' to digits[ 0 ] + '0'.

Hope this helps.
Apr 6, 2010 at 7:53pm
thank you for all your help thus far. right now i am trying to get the comparisons to work mainly the one i am on right now is the equalto. i am overloading the operators instead of functions because i want to be able to use it in the future as a data type. thus i want to overload operators for ease of use later on. the problem i am having right now is that i enter 123 for both objects then display them to check then i try the operator== and i only get false returned even though they are the same number. i checked it some and i found that the problem is somewhere between line 39 and line 44 in the header. please post back with any help you can offer.
Apr 6, 2010 at 8:07pm
Both Duoas and I pointed out the problem in our posts.
Topic archived. No new replies allowed.