大数的四则运算(全)

想要看详细解释的请自行百度,本文直接贴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

在这里插入图片描述

发布了52 篇原创文章 · 获赞 36 · 访问量 4501

猜你喜欢

转载自blog.csdn.net/qq_38861587/article/details/104546369
今日推荐