算法基础---高精度

一、什么是高精度

在c++中int等存储类型最高只能计算少位整数,再大就超出存储空间了。这就需要用数组来存储大整数(例:整数的位数<=10^6的数)。数组中每一个字符表示大整数的一个位数。

二、高精度的类型

//大写字母代表大整数(例:位数<=10^6的数)小整数(例:a<=10^4)

三、各种模板 

  1. 高精度加法
    
    const int N = 1e5 + 10;//避免边界问题
     
    string s1, s2;
    int a[N], b[N], c[N];
     
    int main()
    {
    	cin >> s1 >> s2;
    	int j = 1, k = 1;//a、b数组的下标都是从1开始的
    	for (int i = s1.size() - 1; i >= 0; i--) a[j++] = s1[i] - '0';//倒序输入(让小位在前大位在后便于计算。下同理。
    	for (int i = s2.size() - 1; i >= 0; i--) b[k++] = s2[i] - '0';
     
    	int max = max(s1.size(), s2.size());//记录最大长度
    	int ans = 0;
    	for (int i = 1; i <= max; i++)//相加
    	{
    		ans = ans + (a[i] + b[i]);
    		c[i] = ans % 10;
    		ans = ans / 10;
    	}
     
    	if (ans) c[++max] = ans;//判断最大长度是否需要进位
    	for (int i = max; i >= 1; i--)//再倒序输出,还原位置
    	{
    		cout << c[i];
    	}
    	return 0;
    }

  2. 高精度减法
    
    const int N = 1e5 + 10;
     
    string s1, s2;
    int a[N], b[N], c[N], flag = 0;
     
    int main()
    {
    	cin >> s1 >> s2;
        //判断s1与s2的大小来确定符号
    	if (s1.size() < s2.size() || s1.size() == s2.size() && s1[s1.size()]<s
    2[s2.size])
    	{
    		flag = 1;
    		swap(s1, s2);
    	}
    	int j = 1, k = 1;//a,b下标从1开始
    	for (int i = s1.size() - 1; i >= 0; i--) a[j++] = s1[i] - '0';
    	for (int i = s2.size() - 1; i >= 0; i--) b[k++] = s2[i] - '0';
     
    	int max = max(s1.size(), s2.size());
    	for (int i = 1; i <= ma; i++)//相减  借位处理
    	{
    		if (a[i] - b[i] < 0)
    		{
    			a[i] = a[i] + 10;
    			a[i + 1] = a[i + 1] - 1;
    		}
    		c[i] = a[i] - b[i];
    	}
    	while (c[ma] == 0 && ma > 1) ma--;//前导0的处理
    	if (flag == 1) printf("-");//判断是否为负数
    	for (int i = ma; i >= 1; i--)
    	{
    		cout << c[i];
    	}
    	return 0;
    }

  3. 高精度乘法
    //高精度相乘
    string s1, s2;
    int a[N], b[N], s[N], c[N];
     
    int main()
    {
    	cin >> s1 >> s2;
    	int j = 1, k = 1;
    	for (int i = s1.size() - 1; i >= 0; i--) a[j++] = s1[i] - '0';
    	for (int i = s2.size() - 1; i >= 0; i--) b[k++] = s2[i] - '0';
     
    	for (int i = 1; i <= s1.size(); i++)
    	{
    		for (int j = 1; j <= s2.size(); j++)
    		{
    			s[i + j - 1] += a[i] * b[j];//先将单个位数相乘
    		}
    	}
    	int max = s1.size() + s2.size() - 1;//记录一下最高位数“-1”
    	int ans = 0;
    	for (int i = 1; i <= max; i++)//再用加法高精度的计算
    	{
    		ans = ans + s[i];
    		c[i] = ans % 10;
    		ans = ans / 10;
    	}
    	if (ans) c[++max] = ans;//进位
    	while (c[max] == 0 && max > 1) ma--;//前导0的处理(防止0被相乘)
    	for (int i = ma; i >= 1; i--)
    	{
    		cout << c[i];
    	}
    	return 0;
    }
    //高精度*低精度
    vector<int> mul(vector<int> A, int b)//vector为动态数组可以不用求最高位
    {
        vector<int> C;
        int t = 0;
        for (int i = 0; i < A.size() || t; i ++ )
        {
            if (i < A.size())   t += A[i] * b;
            C.push_back(t % 10);
            t /= 10;
        }
        
        while (C.size() > 1 && C.back() == 0)   C.pop_back();
        
        return C;
    }
     
    int main()
    {
        string a;
        int b;
        vector<int> A;
        cin >> a >> b;
        
        for (int i = a.size() - 1; i >= 0; i -- )   A.push_back(a[i] - '0');
        
        auto C = mul(A, b);
        for (int i = C.size() - 1; i >= 0; i -- )   printf("%d", C[i]);
        
        return 0;
    }

  4.  高精度除法
    
    string s1;
    int a[N], x, c[N];
     
    int main()
    {
    	cin >> s1 >> x;
    	int j = 1;
    	for (int i = s1.size() - 1; i >= 0; i--) a[j++] = s1[i] - '0';
     
    	int max = s1.size(), ans = 0;
    	for (int i = max; i >= 1; i--)//除法
    	{
    		ans = ans * 10 + a[i];//上一位数*10加到下一位
    		c[i] = ans / x;
    		ans = ans % x;
    	}
     
    	while (c[max] == 0 && max > 1) ma--;
    	for (int i = max; i >= 1; i--)
    	{
    		cout << c[i];
    	}
    	cout << ans <<endl;//余数
    	return 0;
    }

  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值