我正在尝试创建一个使用c字符串容纳(理论上)无数个数字的类,因为int有一个限制。我在乘法上遇到很多麻烦,并开始迷惑自己。我是一名学生,因此非常感谢我没有遇到的任何帮助和错误。我已经玩了四个小时了。

当前的问题是我正在正确地计算结果(例如,如果您尝试x = 12且y = 4,那么我只会从中得到8,那么最终答案将变成7,这很奇怪),但它没有正确存储。

定义:

MyInt operator* (const MyInt& x, const MyInt& y)
{
  MyInt steps[x.numDigits - 1]; // Create an array of MyInts

  int carry = 0;           // Holds the 'carry the one'
  int result, xInt, yInt;  // For adding old-school


  // Add each digit separately.
  for (int i = 0; i < x.numDigits; i++)
  {
    steps[i].numDigits = y.numDigits;     // set the numDigits to y's

    // Resize the array to the size of numDigits
    steps[i].Resize(steps[i].numDigits);

    cout << "x.numDigits = " << x.numDigits << '\n';     // DELETE THESE
    cout << "numDigits = " << steps[i].numDigits << '\n';

    // Figure out xInt's value
    xInt = C2I(x.myNumber[x.numDigits - i - 1]);

    // Now multiply xInt by each digit of y
    for (int j = 1; j <= y.numDigits; j++)
    {
      // yInt's value for this run through
      yInt = C2I(y.myNumber[y.numDigits - j]);

      // Answer is xInt * yInt + the remainder
      result = ((xInt * yInt) + carry);
      carry = 0;               // Reset carry to zero

      // If the result is 10 or higher,  carry the excess
      if (result > 9)
      {
    carry = result / 10;
    result = result % 10;
      }

      // Assign result to the appropriate slot in the new number
      steps[i].myNumber[(steps[i].numDigits - j)] = I2C(result);

      cout << "ASSIGNED " << steps[i].myNumber[steps[i].numDigits - j] //DELETE THESE
       << " TO SLOT " << (steps[i].numDigits - j)
       << " with a rem = " << carry << '\n';
    }
    cout << "YOU GOT OUT OF THE J FOR LOOP\n";
    // If carry wasn't reset to 0, that means the loop ended.
    // This means there is a # that cannot fit in the current
    // array size. We must resize, and then assign
    // the extra characters into the array.
    if (carry > 0)
    {
      int carryCopy = carry; // Copy of n for counting numDigits
      int carryCount = 0;    // Counts up how many digits are in carry

      while(carryCopy > 0)   // Figure out how many #'s there are
      {
    carryCopy = carryCopy / 10;
    carryCount++;
      }

      // Figure out the new size
      steps[i].numDigits = steps[i].numDigits + carryCount;

      // Resize to new size
      steps[i].Resize(steps[i].numDigits + carryCount);

      // Copy in the new digits
      for (int k = carryCount-1; k >= 0; k--)
      {
    steps[i].myNumber[k] = I2C(carry % 10);
    carry = carry / 10;
      }
    }
  }
  cout << "What you have so far is " << steps[0] << "\n"; // DELETE
  cout << "YOU GOT TO THE ADDING PART\n";                 // DELETE

  MyInt r = 0; // Create MyInt for total result

  // Add up all of the arrays in steps[] into r
  for (int l = 0; l < x.numDigits - 1; l++)
    r = r + steps[l];

  return r;                   // Result
}

头文件
#include <iostream>// for ostream, istream
using namespace std;

class MyInt
{
   // these overload starters are declared as friend functions

   friend MyInt operator+ (const MyInt& x, const MyInt& y);
   friend MyInt operator* (const MyInt& x, const MyInt& y);

   friend bool operator< (const MyInt& x, const MyInt& y);
   friend bool operator> (const MyInt& x, const MyInt& y);
   friend bool operator<= (const MyInt& x, const MyInt& y);
   friend bool operator>= (const MyInt& x, const MyInt& y);
   friend bool operator== (const MyInt& x, const MyInt& y);
   friend bool operator!= (const MyInt& x, const MyInt& y);

   friend ostream& operator<< (ostream& s, const MyInt& n);
   friend istream& operator>> (istream& s, MyInt& n);

public:
   MyInt(int n = 0);        // first constructor
   MyInt(const char * n);       // second constructor
   ~MyInt();                    // Destructor

   MyInt(const MyInt & n);      // Copy Constructor
   MyInt& operator= (const MyInt & n); // Assignment operator

   // be sure to add in the second constructor, and the user-defined
   //  versions of destructor, copy constructor, and assignment operator

private:

   // member data (suggested:  use a dynamic array to store the digits)
   unsigned int numDigits;  // The number of digits in myInt
   char * myNumber;             // Pointer to dynamic array of digits
   void Resize(unsigned int newSize); // Resize array
};

和我用来测试的主程序:
int main()
{
  // demonstrate behavior of the two constructors and the << overload

  MyInt x(12345), y("9876543210123456789"), r1(-1000), r2 = "14H67", r3;
  char answer;
  cout << "Initial values: \nx = " << x << "\ny = " << y
       << "\nr1 = " << r1 << "\nr2 = " << r2 << "\nr3 = " << r3 << "\n\n";

  // demonstrate >> overload

  cout << "Enter first number: ";
  cin >> x;
  cout << "Enter second number: ";
  cin >> y;

  cout << "You entered:\n";
  cout << "  x = " << x << '\n';
  cout << "  y = " << y << '\n';

  // demonstrate assignment =
  cout << "Assigning r1 = y ...\n";
  r1 = y;
  cout << "  r1 = " << r1 << '\n';

  // demonstrate comparison overloads
  if (x < y)    cout << "(x < y) is TRUE\n";
  if (x > y)    cout << "(x > y) is TRUE\n";
  if (x <= y)   cout << "(x <= y) is TRUE\n";
  if (x >= y)   cout << "(x >= y) is TRUE\n";
  if (x == y)   cout << "(x == y) is TRUE\n";
  if (x != y)   cout << "(x != y) is TRUE\n";

  // demonstrating + and * overloads
  r1 = x + y;
  cout << "The sum (x + y) = " << r1 << '\n';
  r2 = x * y;
  cout << "The product (x * y) = " << r2 << "\n\n";
  cout << "The sum (x + 12345) = " << x + 12345 << '\n';
  cout << "The product (y * 98765) = " << y * 98765 << '\n';
}

最佳答案

您首先要做所有的乘法,然后再进行加法。这效率低下,并使您的代码更加复杂。

相反,您应在计算每个乘法阶段时将结果相加。

例如,代替:

A = 123
B = 456
S[0] = A * (B[2] * 10^2) = 123 * 400 = 49200
S[1] = A * (B[1] * 10^1) = 123 * 50 = 6150
S[2] = A * (B[0] * 10^0) = 123 * 6 = 738
R = S[0] + S[1] + S[2] = 49200 + 6150 + 738 = 56088

做这个:
A = 123
B = 456
R = 0
R += A * (B[2] * 10^2) = 0 + 123 * 400 = 49200
R += A * (B[1] * 10^1) = 49200 + 123 * 50 = 55350
R += A * (B[0] * 10^0) = 55350 + 123 * 6 = 56088

这摆脱了对steps数组的需要(在我的示例中为S)。

另外,请考虑将数字首先存储在数组中的最低有效位。这使您可以将* 10^N步骤替换为索引移位。
A = 123
B = 456
R = 0
R[0:] += A * B[0] = 123 * 6 = 738()
R[1:] += A * B[1] = 123 * 5 + 73 = 688(8)
R[2:] += A * B[2] = 123 * 4 + 68 = 560(88)

其中()部分是通过R的索引移出的数字。该技术还使添加或删除最高有效位变得更加容易,因为它们位于数组的末尾而不是起始位置。

关于c++ - 似乎无法繁复,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8130914/

10-11 21:13