【算法】高精度

【算法】高精度

一.问题引入

第十五届蓝桥杯省赛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;
}
相关推荐
DuHz1 天前
论文精读:大语言模型 (Large Language Models, LLM) —— 一项调查
论文阅读·人工智能·深度学习·算法·机器学习·计算机视觉·语言模型
加农炮手Jinx1 天前
LeetCode 72. Edit Distance 题解
算法·leetcode·力扣
借雨醉东风1 天前
程序分享--常见算法/编程面试题:旋转矩阵
c++·线性代数·算法·面试·职场和发展·矩阵
_深海凉_1 天前
LeetCode热题100-打家劫舍
算法·leetcode·职场和发展
jghhh011 天前
使用 MATLAB 实现支持向量回归 (SVR) 预测未来数据
算法·matlab
云泽8081 天前
笔试算法 - 双指针篇(二):四大经典求和题型 + 有效三角形计数问题
c++·算法
刀法如飞1 天前
【合并已排序数组的三种实现策略,哪一种更可取?】
算法·程序员
王老师青少年编程1 天前
csp信奥赛C++高频考点专项训练之贪心算法 --【区间贪心】:种树
c++·算法·贪心·csp·信奥赛·区间贪心·种树
hi_ro_a1 天前
C++ 哈希表封装 unordered_map /unordered_set
数据结构·c++·算法·哈希算法
Jasmine_llq1 天前
《B4447 [GESP202512 二级] 环保能量球》
数据结构·算法·数学公式计算(核心)·整数除法算法·多组数据循环处理·输入输出算法·简单模拟算法