C++实现大数运算(加减乘除求余)

前言:
只有部分GCC编译器支持int128,而我们平常使用的软件,最大只有_int64.当这些不够用时,我们该怎么办?

我本身想写代码实现整数型大数据的加减乘除和求余,结果写着写着想着连小数运算的也一起写上(反正加的代码不多)

电脑是死的,人是活的,当数据超出范围时,我们可以想其他方法去算,在这里,我使用string类来存数据,string类的容量足够大,相信够一般大数据使用了吧。

编译软件:vs2013

程序功能: 大型整数、小数的加、减、乘、除、求余

代码:

main.cpp

#include <iostream>
#include<string>
#include<cmath>
#include "large.h"
using namespace std;
int main()
{
	char ch;
	string m_snum1, m_snum2;
	while (cin>>m_snum1>>ch>>m_snum2)
	{
		large _large(m_snum1, ch, m_snum2);
	}
	return 0;
}

large.h

#include <iostream>
#include<string>
using namespace std;
class large
{
public:
	large(){}
	large(string m_str1, char m_ch, string m_str2);            //两数的运算
	inline int compare(string str1, string str2); //相等返回0,大于返回1,小于返回-1
	string SUB_INT(string str1, string str2);   //高精度减法
	string ADD_INT(string str1, string str2);         //高精度加法
	string MUL_INT(string str1, string str2);     //高精度乘法 
	string DIVIDE_INT(string str1, string str2, int flag); //高精度除法,flag==1,返回商;flag==0时,返回余数
	string DIV_INT(string str1, string str2); //高精度除法,返回商
	string MOD_INT(string str1, string str2);  //高精度除法,返回余数
	large(large &e);  //拷贝构造
	~large(){};   //析构函数
};

large.cpp

#include <iostream>
#include<string>
#include<cmath>
#include "large.h"
using namespace std;
large::large(string m_str1, char m_ch, string m_str2)//两数的运算
{
	
	int m_ilocation1 ;
	int m_ilocation2 ;
	string m_res;
	int m_istr;
	if (m_str1.find_first_of(".") == -1)
		m_ilocation1 = 0;
	else
		m_ilocation1 = m_str1.length() - m_str1.find_first_of(".") - 1;
	if (m_str2.find_first_of(".") == -1)
		m_ilocation2 = 0;
	else
		m_ilocation2 = m_str2.length() - m_str2.find_first_of(".") - 1;
	if (m_ilocation1 == 0 && m_ilocation2 == 0)
	{
		switch (m_ch)
		{
		case'+':
			m_res = ADD_INT(m_str1, m_str2); break;
		case'-':
			m_res = SUB_INT(m_str1, m_str2); break;
		case'*':
			m_res = MUL_INT(m_str1, m_str2); break;
		case'/':
			m_res = DIV_INT(m_str1, m_str2); break;
		case'%':
			m_res = MOD_INT(m_str1, m_str2); break;
		default:
			break;
		}
	}
		
	else
	{
		int m_ilocat = m_ilocation1 - m_ilocation2;
		int m_ilocation3;
		if (m_ilocation1!=0)
			m_str1.erase(m_str1.find_first_of("."), m_str1.find_first_not_of(".") + 1);
		if (m_ilocation2!=0)
			m_str2.erase(m_str2.find_first_of("."), m_str2.find_first_not_of(".") + 1);
		
		switch (m_ch)
		{
		case'+':
			if (m_ilocat >= 0)
			{
				for (int i = 0; i < m_ilocat; i++)
					m_str2 = m_str2 + '0';
				m_ilocation3 = m_ilocation1;
			}
			else
			{
				for (int i = 0; i < -m_ilocat; i++)
					m_str1 = m_str1 + '0';
				m_ilocation3 = m_ilocation2;
			}
			m_res = ADD_INT(m_str1, m_str2);
			m_istr = m_res.length();
			for (int i = 0; i < m_ilocation3; i++)
				m_istr = m_istr - 1;
			m_res.insert(m_istr, ".");
			break;
		case'-':
			if (m_ilocat >= 0)
			{
				for (int i = 0; i < m_ilocat; i++)
					m_str2 = m_str2 + '0';
				m_ilocation3 = m_ilocation1;
			}
			else
			{
				for (int i = 0; i < -m_ilocat; i++)
					m_str1 = m_str1 + '0';
				m_ilocation3 = m_ilocation2;
			}
			m_res = SUB_INT(m_str1, m_str2);
			m_istr = m_res.length();
			for (int i = 0; i < m_ilocation3; i++)
				m_istr = m_istr - 1;
			m_res.insert(m_istr, ".");
			 break;
		case'*':
			m_ilocation3=m_ilocation1+m_ilocation2;
			m_res = MUL_INT(m_str1, m_str2); 
			m_istr = m_res.length();
			for (int i = 0; i < m_ilocation3; i++)
				m_istr = m_istr - 1;
			m_res.insert(m_istr, "."); break;
		case'/':
			if (m_ilocat >= 0)
			{
				for (int i = 0; i < m_ilocat; i++)
					m_str2 = m_str2 + '0';
			}
			else
			{
				for (int i = 0; i < -m_ilocat; i++)
					m_str1 = m_str1 + '0';
			}
			m_res = DIV_INT(m_str1, m_str2); break;
		case'%':
			m_res = MOD_INT(m_str1, m_str2); break;
		default:
			break;
		}
		

	}
	cout << endl;
	cout << m_res << endl;
}
inline int large::compare(string str1, string str2) //相等返回0,大于返回1,小于返回-1
{
	if (str1.size() > str2.size())
		return 1;
	else if (str1.size() < str2.size())
		return -1;
	else return str1.compare(str2);     //若长度相等,则从头到尾按位比较
}
string large::ADD_INT(string str1, string str2)         //高精度加法
{
	int sign = 1;//sign为符号为
	string str;
	if (str1[0] == '-')
	{
		if (str2[0] == '-')       //负负
		{
			sign = -1;
			str = ADD_INT(str1.erase(0, 1), str2.erase(0, 1));//erase(first,last);删除从first到last之间的字符
		}
		else             //负正
		{
			str = SUB_INT(str2, str1.erase(0, 1));
		}
	}
	else
	{
		if (str2[0] == '-')        //正负
		{
			str = SUB_INT(str1, str2.erase(0, 1));
		}
		else                    //正正,把两个整数对齐,短整数前面加0补齐
		{
			string::size_type L1, L2;  //string::size_type抽象意义是尺寸单位类型
			int i;
			L1 = str1.size();
			L2 = str2.size();
			if (L1 < L2)
			{
				for (i = 0; i < L2 - L1; i++)
					str1 = "0" + str1;
			}
			else
			{
				for (i = 0; i < L1 - L2; i++)
					str2 = "0" + str2;
			}
			int int1 = 0, int2 = 0; //int2记录进位
			for (i = str1.size() - 1; i >= 0; i--)
			{
				int1 = (int(str1[i]) - '0' + int(str2[i]) - '0' + int2) % 10;
				int2 = (int(str1[i]) - '0' + int(str2[i]) - '0' + int2) / 10;
				str = char(int1 + '0') + str;
			}
			if (int2 != 0)str = char(int2 + '0') + str;
		}

	}
	//运算符处理符号
	if ((sign == -1) && (str[0] != '0'))str = "-" + str;
	return str;
}

string large::SUB_INT(string str1, string str2)  //高精度减法
{
	int sign = 1; //sign为符号位
	string str;
	int i, j;
	if (str2[0] == '-')
	{
		str = ADD_INT(str1, str2.erase(0, 1));
	}
	else
	{
		int res = compare(str1, str2);
		if (res == 0)return "0";
		if (res < 0)
		{
			sign = -1;
			string temp = str1;
			str1 = str2;
			str2 = temp;
		}
		string::size_type tempint;
		tempint = str1.size() - str2.size();
		for (i = str2.size() - 1; i >= 0; i--)
		{
			if (str1[i + tempint] < str2[i])          //借位
			{
				j = 1;
				while (1)
				{
					if (str1[tempint - j + i] == '0')
					{
						str1[i + tempint - j] = '9';
						j++;
					}
					else
					{
						str1[i + tempint - j] = char(int(str1[i + tempint - j]) - 1);
						break;
					}
				}
				str = char(str1[i + tempint] - str2[i] + ':') + str;
			}
			else
			{
				str = char(str1[i + tempint] - str2[i] + '0') + str;
			}
		}
		for (i = tempint - 1; i >= 0; i--)
			str = str1[i] + str;
	}
	//去出结果中多余的前导0
	str.erase(0, str.find_first_not_of('0'));
	if (str.empty())str = "0";
	if ((sign == -1) && (str[0] != '0'))str = "-" + str;
	return str;
}

string large::MUL_INT(string str1, string str2)     //高精度乘法 
{
	int sign = 1;
	string str = "0";        //记录当前值
	if (str1[0] == '-')
	{
		sign *= -1;
		str1 = str1.erase(0, 1);
	}
	if (str2[0] == '-')
	{
		sign *= -1;
		str2 = str2.erase(0, 1);
	}
	int i, j;
	string::size_type L1, L2;
	L1 = str1.size();
	L2 = str2.size();
	for (i = L2 - 1; i >= 0; i--)              //模拟手工乘法竖式
	{
		string tempstr;
		int int1 = 0, int2 = 0, int3 = int(str2[i]) - '0';
		if (int3 != 0)
		{
			for (j = 1; j <= (int)(L2 - 1 - i); j++)
				tempstr = "0" + tempstr;
			for (j = L1 - 1; j >= 0; j--)
			{
				int1 = (int3*(int(str1[j]) - '0') + int2) % 10;
				int2 = (int3*(int(str1[j]) - '0') + int2) / 10;
				tempstr = char(int1 + '0') + tempstr;
			}
			if (int2 != 0)tempstr = char(int2 + '0') + tempstr;
		}
		str = ADD_INT(str, tempstr);
	}
	//去除结果中的前导0
	str.erase(0, str.find_first_not_of("0"));
	if (str.empty())str = "0";
	if ((sign == -1) && (str[0] != '0'))str = "-" + str;
	return str;
}

string large::DIVIDE_INT(string str1, string str2, int flag) //高精度除法,flag==1,返回商;flag==0时,返回余数
{
	string quotient, residue;  //定义商和余数
	int sign1 = 1, sign2 = 1;
	if (str2 == "0")   //判断除数是否为0
	{
		quotient = "ERROR!";
		residue = "ERROR!";
		if (flag == 1)return quotient;
		else return residue;
	}
	if (str1 == "0")     //判断被除数是否为0
	{
		quotient = "0";
		residue = "0";
	}
	if (str1[0] == '-')
	{
		str1 = str1.erase(0, 1);
		sign1 *= -1;
		sign2 = -1;
	}
	if (str2[0] == '-')
	{
		str2 = str2.erase(0, 1);
		sign1 *= -1;
	}
	int res = compare(str1, str2);
	if (res < 0)
	{
		quotient = "0";
		residue = str1;
	}
	else if (res == 0)
	{
		quotient = "1";
		residue = "0";
	}
	else
	{
		string::size_type L1, L2;
		L1 = str1.size();
		L2 = str2.size();
		string tempstr;
		tempstr.append(str1, 0, L2 - 1); //将str1中为值0到L2-1的字符串追加到tempstr
		for (int i = L2 - 1; i < L1; i++)  //模拟手工除法竖式
		{
			tempstr = tempstr + str1[i];
			tempstr.erase(0, tempstr.find_first_not_of('0')); //在字符串中查找第一个与'0'不匹配的字符,返回它的位置
			if (tempstr.empty())tempstr = "0";  //q.empty(),当队列空时,返回true
			for (char ch = '9'; ch >= '0'; ch--) //试商
			{
				string str;
				str = str + ch;
				if (compare(MUL_INT(str2, str), tempstr) <= 0)
				{
					quotient = quotient + ch;
					tempstr = SUB_INT(tempstr, MUL_INT(str2, str));
					break;
				}
			}
		}
		residue = tempstr;
	}
	//去除结果中的前导0
	quotient.erase(0, quotient.find_first_not_of("0"));
	if (quotient.empty())quotient = "0";
	if ((sign1 == -1) && (quotient[0] != '0'))quotient = "-" + quotient;
	if ((sign2 == -1) && (residue[0] != '0'))residue = "-" + residue;
	if (flag == 1)return quotient;
	else
		return residue;
}
string large::DIV_INT(string str1, string str2) //高精度除法,返回商
{
	return DIVIDE_INT(str1, str2, 1);
}
string large::MOD_INT(string str1, string str2)  //高精度除法,返回余数
{
	return DIVIDE_INT(str1, str2, 0);
}

运行结果展示:
例子:多位数的小数相加:

这下子就不怕数据超出范围了,欢迎一起探讨,一起交流。

 

  • 24
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
矩阵类的加减乘除运算可以通过重载运算符来实现。以下是一个矩阵类的定义及其运算符重载实现示例: ```C++ #include <iostream> #include <vector> using namespace std; class Matrix { public: Matrix(int rows, int cols) : rows(rows), cols(cols) { data.resize(rows); for (int i = 0; i < rows; i++) { data[i].resize(cols); } } int getRows() const { return rows; } int getCols() const { return cols; } double& operator()(int i, int j) { return data[i][j]; } const double& operator()(int i, int j) const { return data[i][j]; } Matrix operator+(const Matrix& other) const { Matrix result(rows, cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { result(i, j) = (*this)(i, j) + other(i, j); } } return result; } Matrix operator-(const Matrix& other) const { Matrix result(rows, cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { result(i, j) = (*this)(i, j) - other(i, j); } } return result; } Matrix operator*(const Matrix& other) const { Matrix result(rows, other.cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < other.cols; j++) { double sum = 0; for (int k = 0; k < cols; k++) { sum += (*this)(i, k) * other(k, j); } result(i, j) = sum; } } return result; } Matrix operator/(const Matrix& other) const { Matrix result(rows, cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { result(i, j) = (*this)(i, j) / other(i, j); } } return result; } private: int rows, cols; vector<vector<double>> data; }; int main() { Matrix m1(2, 3); m1(0, 0) = 1; m1(0, 1) = 2; m1(0, 2) = 3; m1(1, 0) = 4; m1(1, 1) = 5; m1(1, 2) = 6; Matrix m2(3, 2); m2(0, 0) = 7; m2(0, 1) = 8; m2(1, 0) = 9; m2(1, 1) = 10; m2(2, 0) = 11; m2(2, 1) = 12; Matrix m3 = m1 * m2; for (int i = 0; i < m3.getRows(); i++) { for (int j = 0; j < m3.getCols(); j++) { cout << m3(i, j) << " "; } cout << endl; } return 0; } ``` 在这个示例中,矩阵类的构造函数接受行数和列数,并动态分配内存来存储矩阵数据运算符重载实现中,加、减、乘、除分别对应了 `operator+`、`operator-`、`operator*`、`operator/`。`operator()` 用于访问矩阵元素。在 main 函数中,首先创建了两个矩阵 m1 和 m2,然后计算它们的乘积,并输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cai_niaocainiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值