Link to home
Start Free TrialLog in
Avatar of pflugg
pflugg

asked on

Error in multiplication algorithm

Have the code listed below. Don't understand why the code marked with // ** ? **  doesn't result in c.theInteger being set to the multiplied values. The multiply single digit thing is working correctly (I think) and the general algorithm works (I think). I just can't set the values. Trying to learn and appreciate any help....

void HugeInteger::multiplyHugeIntegers (HugeInteger a, HugeInteger b)
{
     int currentPositiona = 0;
     int currentPositionb = 0;
     int theDigit = 0;
     int curvala = 0;
     int curvalb = 0;
     int n = 0;
     int value = 0;
     int carry = 0;
     HugeInteger c;

     currentPositionb = 40-1;

     while (currentPositionb >= 0)
     {
          theDigit = b.cTheNumber[currentPositionb]-'0';
         c.multiplySingleDigit(a,theDigit,currentPositionb); // ** ? **
          a.outputHugeInteger() ;
         cout << " " << theDigit << "  " << currentPositionb << "  ";
          c.outputHugeInteger() ;
          cout << '\n';
  //      c.addHugeIntegers(cTheNumber,c.cTheNumber);
          currentPositionb--;
     }
}

HugeInteger HugeInteger::multiplySingleDigit (HugeInteger a, int theDigit, int thePosition)
{
     int currentPosition = 0;
     int curvala = 0;
     int curvalb = 0;
     int n = 0;
     int value = 0;
     int carry = 0;
     HugeInteger c;

     currentPosition = 40-1;
     while (currentPosition >= 0)
     {
          curvalb = theDigit;
          curvala = a.cTheNumber[currentPosition]-'0';
          n = curvala * curvalb + carry;
          carry = n/10;
          value = n%10;
          c.cTheNumber[currentPosition-(39-thePosition)] = value + '0';
          currentPosition--;
     }
     if (carry > 0) // an overflow has occurred
     {
          c.initializeTheNumber();
          c.bIsError = true;
     }    
     cout << "*";
     c.outputHugeInteger();
     cout << "*";

     return c;
Avatar of jamesyu
jamesyu

Post out the your head file of class HugeInteger please
Avatar of pflugg

ASKER

// definition of HugeInteger class

#ifndef HugeInteger_H
#define HugeInteger_H

class HugeInteger
{
private:
     char cTheNumber[41];
     bool bIsError;
     void initializeTheNumber();
public:
     HugeInteger();
     int theLength();
    void inputHugeInteger();
     void outputHugeInteger();
     void addHugeIntegers (HugeInteger,HugeInteger);
     void subtractHugeIntegers (HugeInteger,HugeInteger);
     void multiplyHugeIntegers (HugeInteger,HugeInteger);
     HugeInteger multiplySingleDigit (HugeInteger a, int theDigit, int thePosition);
     HugeInteger divideHugeIntegers (HugeInteger,HugeInteger);
     HugeInteger modulusHugeIntegers (HugeInteger,HugeInteger);
     bool isEqualTo (HugeInteger,HugeInteger);
     bool isNotEqualTo (HugeInteger,HugeInteger);
     bool isGreaterThan (HugeInteger,HugeInteger);
     bool isLessThan (HugeInteger,HugeInteger);
     bool isGreaterThanOrEqualTo (HugeInteger,HugeInteger);
     bool isLessThanOrEqualTo (HugeInteger,HugeInteger);
     bool isZero (HugeInteger);
};

#endif
I found the problem,

both multiplyHugeIntegers and multiplySingleDigit return a new HugeInteger object, but you do not capture the new object.

So, change your code

c.multiplySingleDigit(a,theDigit,currentPositionb); // ** ? **
to

c = c.multiplySingleDigit(a,theDigit,currentPositionb); // ** ? **

You also need to define your "assign" function to get the returned value assigned correctly:

HugeInteger HugeInteger::operator=(HugeInteger& h)
your multiplyHugeIntegers do not returned the result value, how do you want to get the result when the calculation is done?
Hi pflugg,

A few comments. You are using a lot of magic numbers (for example "char cTheNumber[41]" (where "41" would be
the "magic number")). Better define constants for those things, like MSB = 41 (where MSB, of course, will be of
some type, for example unsigned or unsigned long, depending on the maximum size (which I guess corresponds
to "number of bits" in your case?) a HugeInteger can have. With MSB defined like this, it will make more sense doing
a thing like:

currentPosition = MSB - 2; // Would be 41 - 2 = 39.

Instead of:

currentPosition = 40-1;

Consider for example what happens if you decide to go
for changing "char cTheNumber[41]" to "char cTheNumber
[46]". All of a sudden your "currentPosition = 40-1;" will not "point" to your MSB (which I guess that you want to
do), but instead to a completely other "bit" (again I am assuming that you are trying to implement (or "simulate")
fixed point arithmetics on data of arbitrary size, am I
right?)

/Ulrik


 



Just out of curiosity, what do you want to do with this?
You are
Avatar of pflugg

ASKER

Can you explain where HugeInteger HugeInteger::operator=(HugeInteger& h) goes and what it does?
Avatar of pflugg

ASKER

urlik: i agree with your magic number thing. is something i intend to go back and change.
ASKER CERTIFIED SOLUTION
Avatar of jamesyu
jamesyu

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
COOL BONUS for pflugg:

overload the operators >, >=, ==, <=, <, !=, *, +, -, then you can use your HugeInteger like this:

HugeInteger a, b, c;
...your code ...
c = a * b;
if (a > b*c){ // or if(a==b+c), if(a!=b), if(a<=b)...... Cool?
    ... your code ...
}


Do you want it??
COOL BONUS for pflugg:

overload the operators >, >=, ==, <=, <, !=, *, /, +, -, *=, /=, +=, -=, then you can use your HugeInteger like this:

HugeInteger a, b, c;
...your code ...
c = a * b - b;
c += a + b;
c /= a * b;
if (a > b*c){ // or if(a==b+c), if(a!=b), if(a<=b)...... Cool?
    ... your code ...
}


add those to your .h file
     int operator> (HugeInteger &h);
     int operator>= (HugeInteger &h);
     int operator== (HugeInteger &h);
     int operator<= (HugeInteger &h);
     int operator< (HugeInteger &h);
     int operator!= (HugeInteger &h);
     friend HugeInteger operator+ (const HugeInteger &h1, const HugeInteger &h2);
     friend HugeInteger operator- (const HugeInteger &h1, const HugeInteger &h2);
     friend HugeInteger operator* (const HugeInteger &h1, const HugeInteger &h2);
     friend HugeInteger operator/ (const HugeInteger &h1, const HugeInteger &h2);
        friend HugeInteger operator+= (HugeInteger &h1, const HugeInteger &h2);
        friend HugeInteger operator-= (HugeInteger &h1, const HugeInteger &h2);
        friend HugeInteger operator*= (HugeInteger &h1, const HugeInteger &h2);
        friend HugeInteger operator/= (HugeInteger &h1, const HugeInteger &h2);


add those functions to your .cpp file:

bool HugeInteger::operator> (HugeInteger &h)
{
     return isEqualTo(*this, h);
}
bool HugeInteger::operator>= (HugeInteger &h)
{
     return isGreaterThan(*this, h) || isEqualTo(*this, h);
}
bool HugeInteger::operator== (HugeInteger &h)
{
     return isEqualTo(*this, h);
}
bool HugeInteger::operator< (HugeInteger &h)
{
     return isLessThan(*this, h);
}
bool HugeInteger::operator<= (HugeInteger &h)
{
     return isLessThan(*this, h) || isEqualTo(*this, h);
}
bool HugeInteger::operator!= (HugeInteger &h)
{
     return isNotEqualTo(*this, h);
}

HugeInteger operator* (const HugeInteger &h1, const HugeInteger &h2)
{
     return multiplyHugeIntegers(h1, h2);  // you need to change your code to return the result
}
HugeInteger operator/ (const HugeInteger &h1, const HugeInteger &h2)
{
     return divideHugeIntegers(h1, h2);
}
HugeInteger operator+ (const HugeInteger &h1, const HugeInteger &h2)
{
     return addHugeIntegers(h1, h2);  // you need to change your code to return the result
}
HugeInteger operator- (const HugeInteger &h1, const HugeInteger &h2)
{
     return subtractHugeIntegers(h1, h2);  // you need to change your code to return the result
}

HugeInteger operator*= (HugeInteger &h1, const HugeInteger &h2)
{
     return h1 = h1 * h2;
}
HugeInteger operator/= (HugeInteger &h1, const HugeInteger &h2)
{
     return h1 = h1 / h2;
}
HugeInteger operator+= (HugeInteger &h1, const HugeInteger &h2)
{
     return h1 = h1 + h2;
}
HugeInteger operator-= (HugeInteger &h1, const HugeInteger &h2)
{
     return h1 = h1 - h2;
}



Have fun.

James