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::multiplyHugeI ntegers (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[currentPositi onb]-'0';
c.multiplySingleDigit(a,th eDigit,cur rentPositi onb); // ** ? **
a.outputHugeInteger() ;
cout << " " << theDigit << " " << currentPositionb << " ";
c.outputHugeInteger() ;
cout << '\n';
// c.addHugeIntegers(cTheNumb er,c.cTheN umber);
currentPositionb--;
}
}
HugeInteger HugeInteger::multiplySingl eDigit (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[currentPositi on]-'0';
n = curvala * curvalb + carry;
carry = n/10;
value = n%10;
c.cTheNumber[currentPositi on-(39-the Position)] = value + '0';
currentPosition--;
}
if (carry > 0) // an overflow has occurred
{
c.initializeTheNumber();
c.bIsError = true;
}
cout << "*";
c.outputHugeInteger();
cout << "*";
return c;
void HugeInteger::multiplyHugeI
{
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[currentPositi
c.multiplySingleDigit(a,th
a.outputHugeInteger() ;
cout << " " << theDigit << " " << currentPositionb << " ";
c.outputHugeInteger() ;
cout << '\n';
// c.addHugeIntegers(cTheNumb
currentPositionb--;
}
}
HugeInteger HugeInteger::multiplySingl
{
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[currentPositi
n = curvala * curvalb + carry;
carry = n/10;
value = n%10;
c.cTheNumber[currentPositi
currentPosition--;
}
if (carry > 0) // an overflow has occurred
{
c.initializeTheNumber();
c.bIsError = true;
}
cout << "*";
c.outputHugeInteger();
cout << "*";
return c;
Post out the your head file of class HugeInteger please
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
#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,th eDigit,cur rentPositi onb); // ** ? **
to
c = c.multiplySingleDigit(a,th eDigit,cur rentPositi onb); // ** ? **
You also need to define your "assign" function to get the returned value assigned correctly:
HugeInteger HugeInteger::operator=(Hug eInteger& h)
both multiplyHugeIntegers and multiplySingleDigit return a new HugeInteger object, but you do not capture the new object.
So, change your code
c.multiplySingleDigit(a,th
to
c = c.multiplySingleDigit(a,th
You also need to define your "assign" function to get the returned value assigned correctly:
HugeInteger HugeInteger::operator=(Hug
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
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
ASKER
Can you explain where HugeInteger HugeInteger::operator=(Hug eInteger& h) goes and what it does?
ASKER
urlik: i agree with your magic number thing. is something i intend to go back and change.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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??
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
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