【算法】高精度

【算法】高精度

一.问题引入

第十五届蓝桥杯省赛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;
}
相关推荐
月华路11 分钟前
G1 GC 对数组与大对象(Humongous)的处理
java·jvm·算法
我想走路带风18 分钟前
LRU和最长前缀和(计算机网络算法)
计算机网络·算法
M78佐菲40 分钟前
Linux学习笔记:进程
linux·笔记·学习·算法
徐小夕2 小时前
表格、文档、甘特、大屏、表单一站打通:pxcharts超级表格4.0正式上线!
前端·算法·github
TechLee3 小时前
跨语言加解密总对不上?这个纯 Go 神库让 AES/RSA 与 PHP、Java 100% 互通
java·后端·算法
月华路5 小时前
G1 新生代对象晋升老年代:实现机制与 GC 日志
java·jvm·算法
万法若空5 小时前
排列组合恒等式
c++·算法
Nil2085 小时前
leetcode 105从前序和中序遍历序列构造二叉树
算法·leetcode·职场和发展
一直C5 小时前
【数据结构】哈希表+算法复杂度与经典排序查找(C语言)
java·linux·开发语言·数据结构·算法·ubuntu·散列表
淡海水5 小时前
04-02-哈希-Dictionary-TKey-TValue-上-核心数据结构
数据结构·算法·c#·哈希算法·编译·字典·dictionary