【算法】高精度

【算法】高精度

一.问题引入

第十五届蓝桥杯省赛B组第四题:

错误解法(未使用高精度算法使得测试数据超出范围)

cpp 复制代码
#include <iostream>
#include<math.h>
using namespace std;
int main()
{
  int n;
  long double d;
  cin>>n>>d;
  d*=pow(2,n);
  long long ans=d;
  if((int)(d*10)%10>=5)
  {
    ans+=1;
    cout<<ans;
  }
  else
  {
    cout<<ans;
  }
  return 0;
}

二.高精度算法概念

1.为什么需要高精度?

C 语言基本数据类型有上限:
int :最大约 20 亿(10 位)
long long :最大约 9e18(18 位)

如果要算 100 位 + 100 位、50 位 × 50 位,普通变量直接溢出,只能用数组存每一位数字,模拟人笔算的过程。

2.高精度核心规则

倒序存储(个位存在数组下标 0)

比如数字 1234,存成:a[0]=4, a[1]=3, a[2]=2, a[3]=1

好处:进位、对位计算最方便。

用int 数组存每一位(不要用 char,计算更方便)。

模拟竖式运算过程。

三.高精度算法模板

1.高精度加法

cpp 复制代码
string add(string a, string b) 
{
    string res;
    int i = a.size() - 1;
    int j = b.size() - 1;
    int carry = 0;
    while (i >= 0 || j >= 0 || carry > 0) 
    {
        int sum = carry;
        if (i >= 0) 
        {
            sum += a[i] - '0';
            i--;
        }
        if (j >= 0) 
        {
            sum += b[j] - '0';
            j--;
        }
        carry = sum / 10;
        res.push_back(sum % 10 + '0');
    }
    reverse(res.begin(), res.end());
    return res;
}

2.高精度减法

cpp 复制代码
bool cmp(string a, string b) 
{
    if (a.size() != b.size()) 
    {
        return a.size() > b.size();
    }
    return a >= b;
}
//高精度减法
string sub(string a, string b) 
{
    bool negative = false;
    if (!cmp(a, b)) 
    {
        negative = true;
        swap(a, b);
    }
    string res;
    int i = a.size() - 1;
    int j = b.size() - 1;
    int borrow = 0;
    while (i >= 0) 
    {
        int x = a[i] - '0';
        int y = 0;
        if (j >= 0) 
        {
            y = b[j] - '0';
            j--;
        }
        x = x - borrow;
        borrow = 0;
        if (x < y) 
        {
            x = x + 10;
            borrow = 1;
        }
        res.push_back(x - y + '0');
        i--;
    }
    while (res.size() > 1 && res.back() == '0') 
    {
        res.pop_back();
    }
    reverse(res.begin(), res.end());
    if (negative) 
    {
        res = "-" + res;
    }
    return res;
}

3.高精度乘法

cpp 复制代码
string mul(string a, string b) 
{
    int n = a.size();
    int m = b.size();
    vector<int> res(n + m, 0);
    for (int i = n - 1; i >= 0; i--) 
    {
        for (int j = m - 1; j >= 0; j--) 
        {
            int x = a[i] - '0';
            int y = b[j] - '0';
            int pos = i + j + 1;
            res[pos] = res[pos] + x * y;
            res[pos - 1] = res[pos - 1] + res[pos] / 10;
            res[pos] = res[pos] % 10;
        }
    }
    string ans;
    for (int k = 0; k < res.size(); k++) 
    {
        int num = res[k];
        if (!(ans.empty() && num == 0)) 
        {
            ans.push_back(num + '0');
        }
    }
    if (ans.empty()) 
    {
        return "0";
    }
    return ans;
}

4.高精度除法

cpp 复制代码
string div(string a, int b, int &rem)
{
    string res;
    rem = 0;
    for (int i = 0; i < a.size(); i++)
    {
        int now = rem * 10 + (a[i] - '0');
        int q = now / b;
        rem = now % b;
        res.push_back(q + '0');
    }
    while (res.size() > 1 && res[0] == '0')
    {
        res.erase(res.begin());
    }
    return res;
}
相关推荐
CoderCodingNo2 小时前
【NOIP】2011真题解析 luogu-P1003 铺地毯 | GESP三、四级以上可练习
算法
iFlyCai3 小时前
C语言中的指针
c语言·数据结构·算法
查古穆3 小时前
栈-有效的括号
java·数据结构·算法
再一次等风来3 小时前
近场声全息(NAH)仿真实现:从阵列实值信号到波数域重建
算法·matlab·信号处理·近场声全息·nah
汀、人工智能3 小时前
16 - 高级特性
数据结构·算法·数据库架构·图论·16 - 高级特性
大熊背3 小时前
利用ISP离线模式进行分块LSC校正的方法
人工智能·算法·机器学习
XWalnut3 小时前
LeetCode刷题 day4
算法·leetcode·职场和发展
蒸汽求职4 小时前
机器人软件工程(Robotics SDE):特斯拉Optimus落地引发的嵌入式C++与感知算法人才抢夺战
大数据·c++·算法·职场和发展·机器人·求职招聘·ai-native
AI成长日志4 小时前
【笔面试算法学习专栏】双指针专题·简单难度两题精讲:167.两数之和II、283.移动零
学习·算法·面试
旖-旎4 小时前
分治(库存管理|||)(4)
c++·算法·leetcode·排序算法·快速选择算法