944,092 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 870
  • C++ RSS
Nov 1st, 2009
0

Help - BigInteger Multiplication using STL List

Expand Post »
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

C++ Syntax (Toggle Plain Text)
  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

C++ Syntax (Toggle Plain Text)
  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

C++ Syntax (Toggle Plain Text)
  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).
Reputation Points: 10
Solved Threads: 0
Newbie Poster
DallasEvertts is offline Offline
10 posts
since Mar 2009

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: telnet server disconnects sockets too quickly
Next Thread in C++ Forum Timeline: Making a basic calculator





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC