Help - BigInteger Multiplication using STL List

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Mar 2009
Posts: 10
Reputation: DallasEvertts is an unknown quantity at this point 
Solved Threads: 0
DallasEvertts's Avatar
DallasEvertts DallasEvertts is offline Offline
Newbie Poster

Help - BigInteger Multiplication using STL List

 
0
  #1
34 Days Ago
For part of my assignment, we are to write a function that overloads the * operator so that we can multiply 2 list<short int>. We are given the BigInt.h and part of BigInt.cpp (It'd be easier if we didn't have to use this format, I know, but we're supposed to add on to this code).

One thing that makes this a bit complicated is how the BigInt is read in. Instead of each node containing a single integer, it contains a block of 3 integers. This is so that the display() function can format the output with correct commas and such, I guess.

Here is the BigInt.h

  1. #include <iostream>
  2. #include <iomanip>
  3. #include <list>
  4.  
  5. #ifndef BIGINT
  6. #define BIGINT
  7.  
  8. const int DIGITS_PER_BLOCK = 3;
  9. class BigInt
  10. {
  11. public:
  12. /***** Constructor *****/
  13. // Let the list<short int> constructor take care of this.
  14.  
  15. void read(istream & in);
  16. void display(ostream & out) const;
  17. BigInt operator+(BigInt addend2);
  18. BigInt operator*(BigInt multiple2);
  19.  
  20. private:
  21. list<short int> myList;
  22. };
  23.  
  24. //------ Input and output operators
  25. inline istream & operator>>(istream & in, BigInt & number)
  26. {
  27. number.read(in);
  28. return in;
  29. }
  30.  
  31. inline ostream & operator<<(ostream & out, const BigInt & number)
  32. {
  33. number.display(out);
  34. return out;
  35. }
  36.  
  37. #endif

And here is the BigInt.cpp

  1. #include <iostream>
  2. #include <cmath>
  3. using namespace std;
  4.  
  5. #include "BigInt.h"
  6.  
  7. //--- Definition of read()
  8. void BigInt::read(istream & in)
  9. {
  10. static bool instruct = true;
  11. if (instruct)
  12. {
  13. cout << "Enter " << DIGITS_PER_BLOCK << "-digit blocks, separated by "
  14. "spaces.\nEnter a negative integer in last block to signal "
  15. "the end of input.\n\n";
  16. instruct = false;
  17. }
  18. short int block;
  19. const short int MAX_BLOCK = (short) pow(10.0, DIGITS_PER_BLOCK) - 1;
  20. for (;;)
  21. {
  22. in >> block;
  23. if (block < 0) return;
  24.  
  25. if (block > MAX_BLOCK)
  26. cerr << "Illegal block -- " << block << " -- ignoring\n";
  27. else
  28. myList.push_back(block);
  29. }
  30. }
  31.  
  32. //--- Definition of display()
  33. void BigInt::display(ostream & out) const
  34. {
  35. int blockCount = 0;
  36. const int BLOCKS_PER_LINE = 20; // number of blocks to display per line
  37.  
  38. for (list<short int>::const_iterator it = myList.begin(); ; )
  39. {
  40. out << setfill('0');
  41. if (blockCount == 0)
  42. out << setfill(' ');
  43.  
  44. if (it == myList.end())
  45. return;
  46.  
  47. out << setw(3) << *it;
  48. blockCount++ ;
  49.  
  50. it++;
  51. if (it != myList.end())
  52. {
  53. out << ',';
  54. if (blockCount > 0 && blockCount % BLOCKS_PER_LINE == 0)
  55. out << endl;
  56. }
  57. }
  58. }
  59.  
  60. //--- Definition of operator+()
  61. BigInt BigInt::operator+(BigInt addend2)
  62. {
  63. BigInt sum;
  64. short int first, // a block of 1st addend (this object)
  65. second, // a block of 2nd addend (addend2)
  66. result, // a block in their sum
  67. carry = 0; // the carry in adding two blocks
  68.  
  69. list<short int>::reverse_iterator // to iterate right to left
  70. it1 = myList.rbegin(), // through 1st list, and
  71. it2 = addend2.myList.rbegin(); // through 2nd list
  72.  
  73. while (it1 != myList.rend() || it2 != addend2.myList.rend())
  74. {
  75. if (it1 != myList.rend())
  76. {
  77. first = *it1;
  78. it1++ ;
  79. }
  80. else
  81. first = 0;
  82. if (it2 != addend2.myList.rend())
  83. {
  84. second = *it2;
  85. it2++ ;
  86. }
  87. else
  88. second = 0;
  89.  
  90. short int temp = first + second + carry;
  91. result = temp % 1000;
  92. carry = temp / 1000;
  93. sum.myList.push_front(result);
  94. }
  95.  
  96. if (carry > 0)
  97. sum.myList.push_front(carry);
  98.  
  99. return sum;
  100. }
  101.  
  102. BigInt BigInt::operator*(BigInt multiple2)
  103. {
  104.  
  105. BigInt sumOfProducts;
  106. short int first, // a block of 1st multiple (this object)
  107. second, // a block of 2nd multiple (multiple2)
  108. result, // a block in their product
  109. carry = 0; // the carry in multiplying two blocks
  110. int count = 0;
  111.  
  112. list<short int>::reverse_iterator // to iterate right to left
  113. it1 = myList.rbegin(), // through 1st list, and
  114. it2 = multiple2.myList.rbegin();// through 2nd list
  115.  
  116. for (it2; it2 != multiple2.myList.rend();++it2)
  117. {
  118. BigInt product;
  119. second = *it2;
  120. while (it1 != myList.rend()) // multiply value of second to entire 1st multiple list
  121. {
  122. first = *it1;
  123. it1++;
  124.  
  125. int temp = first * second + carry;
  126. result = temp % 1000;
  127. carry = temp / 1000;
  128. product.myList.push_front(result);
  129. }
  130. count++;
  131.  
  132. if (carry > 0)
  133. product.myList.push_front(carry);
  134.  
  135. for (int j = 1; j < count; j++) // Take care of adding 0's at the end when second is not in unit's place
  136. product.myList.push_back(0);
  137.  
  138. if (count == 1) // After first multiplication, set the sum of products to the first obtained product
  139. sumOfProducts = product;
  140. else // Adding the products together to get total product
  141. sumOfProducts = sumOfProducts + product;
  142. }
  143. return sumOfProducts;
  144. }

Again, everything but the multiplication function was provided, so we are not allowed to alter that code.

The way I'm trying to tackle this problem is as follows: Suppose you have 1,234 * 5,678. Since nodes are broken into blocks of 3, you would first do 678 * 1,234, then 5,000 * 1,234. However, the problem I'm having is that if I tried to perform this particular example, the 5,000 * 1,234 operation is not occurring.

After many hours of analyzing my code, I believe the problem has to do with the conditions of my main for loop

  1. for (it2; it2 != multiple2.myList.rend();++it2)

If we go back to my example (1234*5678), what's happening is that it does do the 678*1234 operation, but once it2 gets incremented, it won't perform the 5000*1234 operation. What I've been trying to do is come up with some alternate condition to put in here that would essentially be something along the lines of

for (it2; it2 != multiple2.myList.rend()+1;++it2)

However, anything I've tried in order to simulate this gives me a "List Iterator Not Decrementable" fatal error.

I'm also unsure about the correctness of how I'm trying to handle adding x amount of 0's after a number if I need to (just like I would need to add 3 0's after performing 5*1234 in order to get 5000*1234).
Reply With Quote Quick reply to this message  
Reply

Message:



Other Threads in the C++ Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC