我有一个类型BigInt
,它将一个数字数组(0-9)存储在名为private m_digitArray
的char数组中。
我正在重载算术和关系运算符以帮助开发。但是,我无法让乘法运算符*=
为我工作。我发布的代码适用于int * BigInt
中的单个数字操作,但我更喜欢它适用于任何长度编号,适用于所有int * BigInt
,BigInt * int
和特别是BigInt * BigInt
次行动。就像它适用于6 * bigInt(值为6)= 36;但不是11 * bigInt(值为10)。
有问题的重载运算符
BigInt BigInt::operator *= (const BigInt &rhs){
int size = m_digitArraySize + rhs.getSize();
int* C = new int[size];
int s = size-1;
for(int j= rhs.getSize() - 1; j >= 0; j--){
int carry = 0;
int shift = s;
for(int i = m_digitArraySize - 1; i >= 0; i--){
int m = getDigit(i) * rhs.getDigit(j);
int sum = m + C[shift] + carry;
int num = sum % 10;
int c = sum/10;
C[shift] = num;
carry = c;
shift--;
}
C[shift]= C[shift] + carry;
s--;
}
reallocateArray(size);
// for(int i = 0; i < size < ++i){
// m_digitArray[i] = '0' + C[i];
// }
// Nothing being returned, printing to debug
for (int i = 0; i < size; ++i)
{
cout << C[i];
}
return *this;
}
// Overload the * operator for BigInt * BigInt operations
BigInt operator * (const BigInt &lhs, const BigInt &rhs){
return BigInt(lhs) *= rhs;
}
// Overload the * operator for BigInt * int operations
BigInt operator * (const BigInt &lhs, int num){
return BigInt(lhs) *= num;
}
// Overload the * operator for int * BigInt operations
BigInt operator * (int num, const BigInt &rhs){
return BigInt(rhs) *= num;
}
答案 0 :(得分:-1)
嗯,经过一些帮助,我能够弄明白。这是解决问题的方法:
BigInt BigInt::operator *= (const BigInt &rhs){
// Create new BigInt to make changes non-destructively
BigInt numbers;
// A safe capacity size for the new BigInt
int size = m_digitArraySize + rhs.getSize();
// If either number is negative, set self to negative
if(!m_isPositive || !rhs.isPositive())
numbers.initializeArray(size, false);
else
numbers.initializeArray(size, true);
// Go through the multiplier
for(int i = 0; i < rhs.getSize(); ++i){
int carry = 0;
// Go through the multiplicand
for(int j = 0; j < m_digitArraySize; ++j){
// The product of multiplicand and multiplier plus the sum of the previous digits and the carry
int product = (getDigit(j) * rhs.getDigit(i)) + numbers.getDigit(i + j) + carry;
// Reset carry, necessary if the product is just a digit
carry = 0;
// Set carry to the tens digit
carry = product / 10;
// Set product to the units digit
product = product % 10;
// Save to the new BigInt
numbers.setDigit(i +j, product);
}
// Inner loop cuts off near the end, continue the loop if there is a carry
int nextDigit = i + m_digitArraySize;
while(carry!=0){
int new_value = numbers.getDigit(nextDigit) + carry;
carry = 0;
carry = new_value / 10;
new_value = new_value % 10;
numbers.setDigit(nextDigit, new_value);
++nextDigit;
}
}
// Remove excess zeros
numbers.normalizeArray();
*this = numbers;
return *this;
}
答案 1 :(得分:-2)
逻辑中的错误在于您将运算符*编码为实现运算符* =来完成它的工作。你的问题是打电话:
x = z * y
不应该改变&#34; y&#34;的值。这是一个不必要的副作用。但是如果你将BigInt的operator *定义为使用* =来获得结果,那就完全是它的作用。如果你这样做,那么调用
BigInt BigInt::operator*=(const BigInt &rhs)
{
(*this) = (*this) * rhs;
return (*this);
}
将导致不同的行为到&#34; x = y * z&#34;,因为现在z被改变而不是y,这违反了数学的基本交换定律。
使用operator *启动,运算符=,然后构造运算符* =通过将调用链接到那些。
operator *应该创建一个新的BigInt,然后将两个输入BigInts(传递为&#34; const BigInt&amp;&#34;)相乘,然后返回新创建的BigInt。要优化它,请查看移动构造函数。但没有必要。
operator =是你的复制赋值函数,它应该在以后构建为使用移动语义,但这也不重要
之后,您可以使用* =来组合其他两个函数,只需编写简单的内容,例如:
<Input type='text' id='startDatePicker' class='watchlistDateInput' name='startDatePicker' placeholder='<%= data.SearchStart %'>