想要看详细解释的请自行百度,本文直接贴C++代码。
代码涉及到大数的比较、加法、减法,高精度与低精度的乘法、除法(余数),高精度与高精度的乘法。
持续更新中…
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
//大整数的四则运算
struct bign{//定义
int d[1000];
int len;
bign(){//初始化
memset(d, 0, sizeof(d));
len = 0;
}
};
//将整数转换为 bign,例如23456,d[0]=6,...,d[5]=2
bign change(string str)
{
bign a;
reverse(str.begin(), str.end());//逆转
a.len = str.length();
for(int i=0;i<a.len;i++)
a.d[i] = str[i] - '0';
return a;
}
//大数的比较
int compare(bign a, bign b)//1:a大;0:相等;-1:a小
{
if(a.len > b.len)
return 1;
if(a.len < b.len)
return -1;
//a.len == b.len
for(int i=a.len-1;i>=0;i--)
{
if(a.d[i] > b.d[i])
return 1;
else if(a.d[i] < b.d[i])
return -1;
}
return 0;
}
//大数的加法
bign add(bign a, bign b)
{
bign c;
int carry= 0;//进位项
for(int i=0;i<a.len || i < b.len; i++)//以较长的为界限 ,因为一开始已经初始化为0
{
int temp = a.d[i] + b.d[i] + carry;
c.d[c.len++] = temp % 10;
carry = temp / 10;
}
if(carry != 0)
c.d[c.len++] = carry;
return c;
}
//大数的减法
//注意:使用sub函数前要先调用compare函数比较两个数的大小 ,如果被减数小于减数,需要交换两个变量,然后输出负号。
bign sub(bign a, bign b)//a-b
{
bign c;
for(int i=0; i<a.len || i<b.len; i++) //以较长的为界限
{
if(a.d[i] < b.d[i])//不够减
{
a.d[i+1]--;
a.d[i] +=10;
}
c.d[c.len++] = a.d[i] - b.d[i];
}
//去掉高位的0,同时保留至少一位
while(c.len > 1 && c.d[c.len-1] == 0)
c.len--;
return c;
}
//高精度与低精度的乘法
//注意:如果a和b中存在负数,需要先记录下其符号,然后取他们的绝对值代入函数。
bign multi(bign a, int b)
{
bign c;
int carry = 0;//进位
for(int i=0;i<a.len;i++)
{
int temp = a.d[i] * b + carry;
c.d[c.len++] = temp % 10;//最低位作为结果, 其余位为进位
carry = temp / 10;
}
//处理进位,与加法不同,此时carry可能涉及多位数
while(carry != 0)
{
c.d[c.len++] = carry % 10;
carry /= 10;
}
return c;
}
//高精度与高精度的乘法
//注意:如果a和b中存在负数,需要先记录下其符号,然后取他们的绝对值代入函数。
bign doubleMulti(bign a, bign b)
{
bign c;
for(int i=0;i<a.len;i++)
for(int j=0;j<b.len;j++)//正着乘 ,暂时不考虑进位问题
c.d[i+j] += (a.d[i] * b.d[j]);
//处理进位
for(int i=0;i<a.len+b.len;i++)
{
c.d[i+1] += c.d[i] / 10;
c.d[i] %= 10;
}
//判断有效位数
for(int i=a.len+b.len;i>=0;i--)
if(c.d[i] != 0)
{
c.len = i+1;
break;
}
return c;
}
//高精度与低精度的除法
bign divide(bign a, int b, int &r)//a/b,其中r为余数
{
bign c;
c.len = a.len;//先令与a的长度相等
for(int i=a.len-1;i>=0;i--){//从高位开始
r = r * 10 + a.d[i];//和上一位遗留下来的余数组合
if(r > b){
c.d[i] = r / b;//商
r %= b;//新的余数
}
else
c.d[i] = 0;
}
//处理一开始有0的情况,保留至少一位
while(c.len > 1 && c.d[c.len - 1] == 0)
c.len--;
return c;
}
//输出
void print(bign a)
{
for(int i=a.len-1;i>=0;i--)
cout<<a.d[i];
cout<<endl;
}
int main()
{
freopen("in.txt", "r",stdin);
string str1 = "1111111111";
int b = 10;
//预处理
bign a = change(str1);
//加
cout<<"******************加**********************"<<endl;
bign c = add(a,a);
print(c);
//减
cout<<"******************减**********************"<<endl;
c = sub(a,a);
print(c);
//乘
cout<<"******************乘**********************"<<endl;
c = multi(a, b);
print(c);
//双精度相乘
cout<<"******************double乘**********************"<<endl;
c = doubleMulti(change("123"), change("123"));
print(c);
//除
cout<<"******************除**********************"<<endl;
int r = 0;
c = divide(a, b, r);
print(c);
cout<<"余数r:"<<r<<endl;
return 0;
}
结果:
******************加**********************
2222222222
******************减**********************
0
******************乘**********************
11111111110
******************double乘**********************
15129
******************除**********************
111111111
余数r:1