【算法】高精度

【算法】高精度

一.问题引入

第十五届蓝桥杯省赛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,存成:a0=4, a1=3, a2=2, a3=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;
}
相关推荐
yi01111 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
灯澜忆梦14 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
小蒋观天下14 小时前
专项方案:大场景港口AI安防、多干扰环境下的算法调优与落地实操
人工智能·深度学习·算法·安全·机器学习·计算机视觉·ai大模型
Evand J14 小时前
【电机滤波例程5】渐消因子自适应扩展卡尔曼滤波(EKF),MATLAB。PMSM负载突变下的状态估计。附下载链接
算法·matlab
H.莓飛14 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
好想像大佬一样能够ak所有15 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
aqiu11111115 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
黄金龙PLUS15 小时前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密
不会就选b15 小时前
算法日常・每日刷题--<动态规划>14
算法
赛博守夜人15 小时前
跨境业务与出海合规之九:海外买量投放与营销虚假流量(Ad Fraud):跨国机房群控与归因欺诈识别算法
算法·安全