乐趣区

关于算法:大数运算

大数运算

学校大作业要求实现任意大数(可带小数局部)的加减乘除,如果有小数则须要保留 10 位小数,我采纳了 vector 容器把每一位的数字的贮存下来,再通过如同小学竖式计算来实现。那么实际上实现难度不高,惟一难度就是大数除法的实现。而通过对齐除数与被除数,逐位屡次相减,则可得出对应位的商。保留 10 位小数,那么求商就要求到第 11 位,则被除数后要接上 11 减去被除数小数长度加上除数小数长度个 0,求出后果后再四舍五入即可。

除法运算实现代码

vector<short> divide(vector<short>number1, vector<short>number2, short decimal_length1, short decimal_length2, short decimal_length) {
 vector<short> number;
 number.reserve(60);
 while (!number2[0]) number2.erase(number2.begin());
 short extra_zero = decimal_length - decimal_length1 + decimal_length2;
 short former_number2_size = number2.size();
 for (short i = 0;i < extra_zero;i++)
 number1.insert(number1.end(), 0);
 while (number2.size() < number1.size())
 number2.insert(number2.end(), 0);
 while (number2.size() >= former_number2_size) {
 short digit_result = 0;
 short former_number1_size = number1.size();
 while (1) {if (number1.size() == number2.size()) {
 short i = 0;
 for (;i < number1.size() - 1 && number1[i] == number2[i];i++);
 if (number1[i] - number2[i] < 0)
 break;
 }
 if (number1.size() < number2.size())
 break;
 number1 = subtract_for_divide(number1, number2);
 carry(number1);
 digit_result++;
 }
 number.push_back(digit_result);
 number2.pop_back();}
 return number;
}
​
void carry_for_mutiple_and_divide(vector<short>& number, short& decimal_length) {for (short j = number.size() - 1;j >= 0;j--) {if (number[j] >= 10) {if (!j) {number.insert(number.begin(), number[j] / 10);
 number[1] %= 10;
 j++;
 }
 else {number[j - 1] += number[j] / 10;
 number[j] %= 10;
 }
 }
 else if (number[j] < 0) {number[j] += 10;
 number[j - 1]--;
 }
 }
 while (!number[0] && number.size() > 0 && number.size() - decimal_length > 1)
 number.erase(number.begin());
 while (decimal_length > 0 && *(number.end() - 1) == 0) {number.pop_back();
 decimal_length--;
 }
}

大数运算实现代码

Source
办法挺笨的,写了差不多 500 行。(用 c ++ 实现)

发明的 vector 数组都应用了 reserve,尽管会占用稍多的内存,但能够缩小裁减数组(须要将整个 vector 数组块复制到另一块更大的内存)的次数,从而进步运行速度。

退出移动版