C++ Can';Don’’我似乎不会以艰难的方式成倍增长

C++ Can';Don’’我似乎不会以艰难的方式成倍增长,c++,dynamic,C++,Dynamic,我正试图创建一个类,该类使用c字符串保存(理论上)无限数量的数字,因为int有一个限制。我在乘法方面遇到了很多麻烦,开始把自己搞糊涂了。我是一名学生,所以任何我没有发现的帮助和错误都非常感谢。我已经玩了4个小时的乘法了 目前的问题是,我计算的结果是正确的(比如,如果你尝试x=12,y=4,我只能从中得到8,然后最终的答案变成7,这是奇数),但它没有正确存储 定义: MyInt operator* (const MyInt& x, const MyInt& y) { MyInt

我正试图创建一个类,该类使用c字符串保存(理论上)无限数量的数字,因为int有一个限制。我在乘法方面遇到了很多麻烦,开始把自己搞糊涂了。我是一名学生,所以任何我没有发现的帮助和错误都非常感谢。我已经玩了4个小时的乘法了

目前的问题是,我计算的结果是正确的(比如,如果你尝试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
}
MyInt运算符*(常量MyInt&x,常量MyInt&y)
{
MyInt步骤[x.numDigits-1];//创建一个MyInt数组
int carry=0;//保存“carry the one”
int result,xInt,yInt;//用于添加旧学校
//分别添加每个数字。
对于(int i=0;icout我注意到的一件事是,
steps
的初始化大小为
x.numDigits-1
,但是for循环超过了数组的末尾。也许你的意思是这个
steps
的大小应该是
x.numDigits
。除此之外,可能还有其他错误。

你先做所有的乘法,然后是adding。这是低效的,并使您的代码更加复杂

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

例如,而不是:

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
这样就不需要
步骤
数组(在我的示例中是
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
移动过去的数字。这种技术还可以更轻松地添加或删除最重要的数字,因为它们位于数组的末尾而不是开头。

建议:返回代码并插入注释,精确解释每行的作用以及原因。请在不同位置指定点,哪些变量包含哪些值。完成时,您可能已经发现了3-4个错误。您鲁莽地使用
new
和原始指针无疑会使整个过程在某个点上爆炸。为什么不使用现有的标准库组件进行动态内存管理?正如我所说,我是一名学生,所以我会除了上面的命令,我不知道还有什么其他的方法。你有什么建议?@jordaninternets:我会从一个
std::vector
或类似的东西开始来保存数字。我想你用的是base-256?我会说他用的是base-10,std::vector会更好,但考虑到这是一个家庭作业,可能会有一些限制允许。当然有:[谢谢你,虽然我不理解你的评论。你修复了这个错误吗?我修复了这个错误,但我对你关于存在其他错误的评论说是的。这不是一个大错误。很抱歉反应太长,但在重写之后,我终于让它起作用了!我在这个过程中学到的另一个对初学者来说的关键是将很多东西分成不同的部分函数。这样,它就不会这么快变得混乱。非常感谢!是的,这是一个很大的步骤:学习什么需要被分离成函数。作为记录,GNU
gmp
库优化了任意精度的数学。
gcc
使用它,所以如果你有
gcc
,你可能有
gmp
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
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)