写在开头:
大数的运算一直以来都是一个具有研究性的问题, 自己动手模拟了一下笔算乘法, 以及由乘法拓展出来的阶乘, 和大家分享一下思路及代码
基本概念及背景
- 大数: 我们把运算结果超出计算机数据类型范围的数, 称之为大数 (
胡扯中)
比如50的阶乘结果是65位, 而 int 的范围是 10 ^ 9, long long 的范围是 10 ^ 18
- 由于运算结果已经远远超出计算机能表达的范围了,因此衍生出模拟笔算乘法, 并且使用数组, 来保存运算结果的方法
大数乘法
思路
模拟笔算乘法, 如图
由于我们对笔算乘法已经了然于心, 因此几乎不用思考就能算出结果, 但是如果我们慢下来一步一步思考, 我们可以发现一些规律
- 计算乘法时, 每次都是拿 23 的一位数, 与 123 相乘, 相乘次数是 2 次, 即 23 的位数;
- 而拿3 或 2 与 123 相乘时, 相乘次数是3, 即123的位数;
- 计算加法时, 每次都需要向左偏移一位
发现这些规律后, 可以发现
- 第 1 步是一个大循环, 循环次数为 23 即第二个数的位数
- 第 2 步和第 3 步, 是内部的小循环, 循环次数分别是, 123 即第一个数的位数, 和 23 的位数减一
开始动手
代码实现
模拟笔算乘法
为了方便, 我从下标 0 开始处理数据, 读取后需要逆转一下数据, 所以我先使用字符数组(即字符串)读取数据, 处理后在转移到整形数组
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define Int(x) (x - '0')
int main() {
int num1[105] = {
0}, num2[105] = {
0}, ret[205] = {
0};
char n1[105], n2[105];
scanf("%s%s", n1, n2);
//这几步只是单纯方便读取及逆序处理
int len1 = strlen(n1), len2 = strlen(n2