1

I'm making 2 Hugeint objects with this constructor

HugeInt.h

public: 
    static const int digits = 30; // maximum digits in a Hugelnt 
    HugeInt( long = 0 ); // conversion/default constructor 
    HugeInt( const string & ); // conversion constructor 
    //addition operator; Hugelnt + Hugelnt 
    HugeInt operator+( const HugeInt & ) const; 
private: 
short integer[ digits ]; 

first I convert my int or string into an integer array

HugeInt.cpp

HugeInt::HugeInt( long value)
{ 
    // initialize array to zero 
    for ( int i = 0; i < digits; i++ ) 
        integer[i] = 0; 
        
    // place digits of argument into array 
    for ( int j = digits - 1; value != 0 && j>= 0; j-- ) 
    { 
        integer[j] = value % 10; 
        value /= 10; 
    } // end for 
} // end Hugelnt default/conversion constructor 
// conversion constructor that converts a character string 
// representing a large integer into a HugeInt object 
HugeInt::HugeInt( const string &number) 
{
    // initialize array to zero 
    for ( int i = 0; i < digits; i++ ) 
        integer[i] = 0; 
    
    // place digits of argument into array 
    int length = number.size(); 
    
    for ( int j = digits - length, k = 0; j < digits; j++, k++ ) 
        if ( isdigit( number[ k])) // ensure that character is a digit 
            integer[j] = number[ k ] - '0'; 
} // end Hugelnt conversion constructor

operator+ for HugeInt + HugeInt

HugeInt HugeInt::operator+( const HugeInt &op2 ) const
{ 
    HugeInt temp; // temporary result 
    int carry = 0; 
    
    for ( int i = digits - 1; i >= 0; i-- ) 
    { 
        temp.integer[i] = integer[i] + op2.integer[i] + carry; 
        
        // determine whether to carry a 1 
        if ( temp.integer[i] > 9) 
        { 
            temp.integer[i] %= 10; // reduce to 0-9 
            carry = 1; 
        } // end if
         else // no carry 
            carry = 0; 
    } // end for 
    
}

operator<< to output the HugeInt

ostream& operator<<( ostream &output, const HugeInt &num ) 
{ 
    int i; 
    
    for (i = 0; ( num.integer[i] == 0 ) && ( i <= HugeInt::digits ); i++ )
        ;// skip leading zeros
        
    if ( i == HugeInt::digits ) 
        output << 0 ; 
    else 
        for (; i < HugeInt::digits; i++ ) 
            output << num.integer[i]; 
        
    return output; 
} // end function operator<<

in main.cpp it looks like this.

HugeInt n3( "9999999999999999999999999999999999" ); 
HugeInt n4( "1" ); 
cout <<"n6 = n3 + n4 = " << n3 << " + "<< n4 << " = " << n3+n4 << "\n\n";

But the output become random numbers

n6 = n3 + n4 = 9999999999999999999999999999999999 + 1 = 23919128293276100-2095744600-20957446000006832-2095744606848-2095744607519200006000-20957

I add return temp at the end of operator+, the result becomes = 0 if I add return *this, the results become = 9999999999999999999999999999999999

the result should be 10000000000000000000000000000000000

Please help explain this to me, my English is bad so sorry for bad question.

  • Not that it's relevant to your example, given you use the `string` constructor, but your `long` constructor is using `value = 10;` when you almost certainly mean `value /= 10;`. I suspect one or both of your initialization loops is wrong as well. If it's not wrong, it's just weird to have array based bigints with bigendian orientation of the array (I've seen at least four such implementations, for GMP, Python `int`, Rust BigNum, and Java BigInteger, and while I might be mistaken on the last two [been awhile], I believe all four of them have little endian words (lowest word is always index 0). – ShadowRanger Apr 15 '22 at 03:52
  • Oops, yeah you're right, I mean value/= 10; I will think about my constructors – Marco Van Houten Prawongso Apr 15 '22 at 03:58
  • 1
    `num.integer[i] == 0 ` this leads to Undefined Behavior when `i == digits`. Undefined Behavior explains your weird output. – bolov Apr 15 '22 at 04:00
  • 1
    your operator+ doesnt retrun anything – pm100 Apr 15 '22 at 04:22
  • Yeah, that could be the problem, still thinking about what to return, also thinking about alternative method. – Marco Van Houten Prawongso Apr 15 '22 at 04:29
  • Yes but it is declared as returning a HugeInt – pm100 Apr 15 '22 at 04:32
  • Side-note: I strongly recommend you read [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/q/4421706/364696) Among other things, the implementation of `operator+` should almost always be: 1) A non-member function, and 2) A ridiculously trivial implementation that delegates *all* of the work to the copy/move constructor (by receiving the left argument by value) and the member function, `operator+=` (which contains the real logic of adding). If you go the way you're going, you'll reimplement the same logic *many* times, and do so poorly. – ShadowRanger Apr 15 '22 at 04:44
  • Ok, thanks for your advice, I'm still freshmen, a lot of things to learn. thank you all! – Marco Van Houten Prawongso Apr 15 '22 at 04:56

1 Answers1

0

Your major problem is that you hard code maximum number of digits you can deal with to 30

But

 9999999999999999999999999999999999
 1234567890123456789012345678901234

this string is 34 digits

Plus you build the result of the add into 'temp' but do nothing with it

added

 return temp;

increased digits to 40

 n6 = n3 + n4 = 9999999999999999999999999999999999 + 1 = 10000000000000000000000000000000000
pm100
  • 48,078
  • 23
  • 82
  • 145
  • @MarcoVanHoutenPrawongso I debugged your code easily by changing from a raw array to std::vector, or you could use std::array since you want fixed size Both do bounds checking for you in debug mode. In general do no use naked arrays in c++ – pm100 Apr 15 '22 at 04:54