【算法】高精度

【算法】高精度

一.问题引入

第十五届蓝桥杯省赛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;
}
相关推荐
leo__5202 小时前
MHT多假设跟踪算法(Multiple Hypothesis Tracking)MATLAB实现
开发语言·算法·matlab
ShineWinsu2 小时前
对于C++中unordered_set的详细介绍
数据结构·c++·算法·面试·stl·哈希表·unordered_set
吃着火锅x唱着歌2 小时前
LeetCode 456.132模式
数据结构·算法·leetcode
二木九森2 小时前
LeetCode-寻找环形链表的入口
算法·leetcode·链表
飞Link2 小时前
耳机连接电脑时调节耳机音量电脑音量也会随着改变
算法·电脑
此方ls2 小时前
机器学习聚类算法一——K均值
算法·机器学习·聚类
再难也得平2 小时前
力扣73. 矩阵置零(Java解法)
算法·leetcode·矩阵
进击切图仔2 小时前
生成 .so 和使用 .so
java·javascript·算法
样例过了就是过了2 小时前
LeetCode热题100 岛屿数量
数据结构·c++·算法·leetcode·dfs