高精度算法(加、减、乘、除,使用c++实现)

一、概念

在我们进行计算的过程中,经常会遇到几十位,甚至几百位的数字的计算问题,也有可能会遇到小数点后几十位,几百位的情况,而我们面对这样的情况下,long long  和 double 的数据范围显然是不够使用的了。因此这时,我们就需要引入一个新的算法,叫做高精度算法。

高精度算法:它是处理大数字的数学计算方法,在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除等运算。

思想:高精度算法本质上是用字符串模拟数字进行计算,再利用类似于数学里的竖式的形式,一位一位进行相关计算 。

注意事项:

高精度加法:

  1. 倒叙输入,倒序输出,但中间是正着运算;
  2. 相加之后的进位处理;

高精度减法:

  1. 考虑结果出现的正情况;
  2. 前导0的处理;
  3. 考虑减法的借位处理;

高精度乘法:

  1. 前导0的处理(0被相乘);
  2. 可以将乘法单个位数相乘再转化成加法的思想;
  3. 此时题目中没有涉及到负数的情况。如出现负数,只需考虑两个字符串第一位是否为负号,然后结尾特殊判断一下即可;

高精度除法:(高精度÷低精度)

  1. 输入、计算、输出、需要同时逆序或同时正序;
  2. 前导0的处理;
  3. 不能考虑进位的情况

二、数据的处理

2.1 数据的存储

当输入的数很长时,可采用字符串方式输入,这样可输入位数很长的数,利用字符串函数和操作运算,将每一位取出,存入数组中 。

void init(int a[]) { // 传入数组string s;cin >> s; len = s.length(); // s.length --> 计算字符串位数for(int i=1; i<=len; i++)     a[i] = s[len -i] - '0'; //将字符串s转换为数组a, 倒序存储
}

2.2 借位和进位 

// 加法进位: c[i] = a[i] + b[i]code:    if(c[i] >= 10) {c[i] %= 10;++c[i++];}//减法借位: c[i] = a[i] - b[i]code:    if(a[i] < b[i]) {--a[i+1];a[i] += 10;   } //乘法进位: c[i + j - 1] = a[i] * b[j] + x + c[i + j - 1];x = c[i + j - 1] / 10;c[i + j - 1] % 10;

三、加法

#include<iostream>
#include<cstring>
#include<vector>using namespace std;int main()
{char s1[500], s2[500];int a[500] = { 0 }, b[500] = { 0 }, c[501] = { 0 };int i = 0;vector<int>vec_add;cin >> s1 >>s2;int len_s1 = strlen(s1);//求两个“数字”位数int len_s2 = strlen(s2);for (i = 0;i < len_s1;i++){a[i] = s1[len_s1 - i - 1] - '0';//倒叙存储,方便最高位进位,按字符型输入,按整型的方式存储在数组里面}for (i = 0;i < len_s2;i++){b[i] = s2[len_s2 - i - 1] - '0';}for (i = 0;i < (len_s1 > len_s2 ? len_s1 : len_s2);i++){ vec_add.push_back(a[i] + b[i] + c[i]);if (vec_add[i] >= 10)//如果可以进位{c[i + 1] = vec_add[i] / 10;vec_add[i] %= 10;if (i == (len_s1 > len_s2 ? len_s1 : len_s2)){vec_add.push_back(1);}}}int len_vec_add = vec_add.size();for (i = len_vec_add - 1;i >= 0;i--){cout << vec_add[i];}cout << endl;return 0;
}

运行示例如下:

四、减法

#include<iostream>
#include<cstring>
#include<vector>int main()
{char s1[500], s2[500];int a[500] = { 0 }, b[500] = { 0 }, c[501] = { 0 };int i = 0;vector<int>vec;cin >> s1 >> s2;int len_s1 = strlen(s1);//求两个“数字”位数int len_s2 = strlen(s2);for (i = 0;i < len_s1;i++){a[i] = s1[len_s1 - i - 1] - '0';//倒叙存储,方便最高位进位,按字符型输入,按整型的方式存储在数组里面}for (i = 0;i < len_s2;i++){b[i] = s2[len_s2 - i - 1] - '0';}for (i = 0;i < (len_s1 > len_s2 ? len_s1 : len_s2);i++){if (strcmp(s1, s2) >= 0){vec.push_back(a[i] - b[i]);if (vec[i] < 0){a[i + 1] -= 1;a[i] += 10;vec[i] += 10;}}else{vec.push_back(b[i] - a[i]);if (vec[i] < 0){b[i + 1] -= 1;b[i] += 10;vec[i] += 10;}}}int len_vec = vec.size();if (strcmp(s1, s2) >= 0){for (i = len_vec - 1;i >= 0;i--){cout << vec[i];}}else{cout << "-";for (i = len_vec - 1;i >= 0;i--){cout << vec[i];}}cout << endl;return 0;
}

运行结果如下:

五、乘法

大数乘法可以看成多个数大数乘以一位的数再相加

  1. 输入与初始化
    • 从用户那里接收两个字符串s1s2,它们代表两个大整数。
    • 将这两个字符串转换为数组ab,使得数组中的元素是从低位到高位存储的整数。这是通过将字符串中的每个字符减去字符'0'的ASCII值来实现的,因为字符'0'到'9'的ASCII值是连续的。
    • 初始化一个整数数组c,用于存储进位值。
    • 初始化一个std::vector<int>(名为vec),用于存储最终的乘积结果。
  2. 计算乘积
    • 使用两层循环来计算ab中每个元素的乘积,并累加到vec中。
    • 外层循环遍历a中的每个元素,内层循环遍历b中的每个元素。
    • 对于ab中的每对元素,计算它们的乘积,并加上之前的进位值(如果有的话)。
    • 将乘积的个位数加到vec的对应位置,并更新进位值。
  3. 处理进位
    • 进位逻辑在内层循环结束后处理。如果最后一个乘法操作后存在进位,需要将其加到vec的下一个位置。
    • 需要注意,由于vec的大小在循环过程中是变化的,因此直接通过索引访问vec可能会导致越界错误。正确的做法是在需要添加新元素时,使用vec.push_back()

代码示例如下:

int main()
{char s1[500], s2[500];int a[500] = { 0 }, b[500] = { 0 };int i = 0;int z = 0;vector<int>vec;cin >> s1 >> s2;int len_s1 = strlen(s1);//求两个“数字”位数int len_s2 = strlen(s2);//初始化vec的大小至少为len_s1 + len_s2,这样可以保证在计算过程中不会越界。vec.resize(len_s1 + len_s2, 0);for (i = 0;i < len_s1;i++){a[i] = s1[len_s1 - i - 1] - '0';//倒叙存储,方便最高位进位,按字符型输入,按整型的方式存储在数组里面}for (i = 0;i < len_s2;i++){b[i] = s2[len_s2 - i - 1] - '0';}for (i = 0; i < len_s1; i++){int carry = 0; // 每次循环开始时,进位为0  for (int j = 0; j < len_s2; j++){// 计算乘积,加上已有的值和进位int product = a[i] * b[j] + vec[i + j] + carry;   vec[i + j] = product % 10; // 取个位数  carry = product / 10; // 更新进位  }// 检查最后一个乘法操作后的进位  if (carry > 0){vec[i + len_s2] += carry;}}// 处理vec中可能的前导0 while (!vec[vec.size() - 1]){if (vec[vec.size() - 1] == 0){vec.pop_back();}}int len_vec = vec.size();for (i = len_vec - 1;i >= 0;i--){cout << vec[i];}cout << endl;return 0;
}

 测试输出结果如下:

六、除法

高精度除以低精度:

思路:

除法时,每一次的商值都在 0~9 之间,每次求得的余数连接以后的若干位得到新的被除数,继续做除法。因此,在做高精度除法时,要涉及到乘法运算和减法运算,还有移位处理。当然,为了程序简洁,可以避免高精度乘法,用 0~9 次循环减法取代得到商的值。采用按位相除法

#include<iostream>int main()
{char n1[100];int a[100] = { 0 }, c[100] = { 0 }, i, x = 0, b;cin >> n1 >> b;int len_a = strlen(n1);for (i = 1; i <= len_a; i++){a[i] = n1[i - 1] - '0'; //除法不需要逆序存放}for (i = 1; i <= len_a; i++){c[i] = (a[i] + x * 10) / b;  // 算上上一位剩下的继续除x = (a[i] + 10 * x) % b; // 求余}int len_c = 1;while (c[len_c] == 0 && len_c < len_a){len_c++;}for (i = len_c; i < len_a; i++){cout << c[i];}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/294900.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Node.js-知识点学习总结归纳

Node.js-知识点学习总结归纳 安装nodenode运行方式通过Node.js直接运行js文件&#xff08;也就不用通过网页html了&#xff09;绝对路径调用:相对路径调用&#xff1a;直接运行js命令&#xff1a; Vscode控制台使用node运行js文件 安装node 这个就不用讲了吧&#xff0c;网上搜…

开源知识库平台Raneto--使用Docker部署Raneto

文章目录 一、Raneto介绍1.1 Raneto简介1.2 知识库介绍 二、阿里云环境2.1 环境规划2.2 部署介绍 三、环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Raneto镜像五、部署Raneto知识库平台5.1 创建挂载目录5.2 编辑config.js文件5.3 编…

Sui Basecamp日程公布,两天超50场密集分享等你来参加

随着4月的来临&#xff0c;我们也怀着激动的心情迎来了Sui全球旗舰品牌会议Sui Basecamp的个位数倒计时。 Sui Basecamp将在4月10–11日巴黎区块链周期间举行&#xff0c;Web3构建者、知名企业和信仰者齐聚一堂&#xff0c;在这里共同创造、学习和建立联系。Basecamp将由具有对…

左值与右值,以及c++11的相关特性。

目录 左值 右值 左值引用总结&#xff1a; 右值引用总结&#xff1a; 右值引用使用场景和意义&#xff1a; 1、左值引用的使用场景&#xff1a; 编译器优化1&#xff1a; 2、移动构造与移动赋值&#xff1a; 3、右值引用的使用场景&#xff1a; 编译器优化2&#xff1a…

excel匹配替换脱敏身份证等数据

假如excel sheet1中有脱敏的身份证号码和姓名&#xff0c;如&#xff1a; sheet2中有未脱敏的数据数据 做法如下&#xff1a; 1、在sheet2的C列用公式 LEFT(A2,6)&REPT("*",8)&RIGHT(A2,4) 做出脱敏数据&#xff0c;用来与sheet1的脱敏数据匹配 2、在sheet…

【卫星家族】 | 高分六号卫星影像及获取

1. 卫星简介 高分六号卫星&#xff08;GF-6&#xff09;于2018年6月2日在酒泉卫星发射中心成功发射&#xff0c;是高分专项中的一颗低轨光学遥感卫星&#xff0c;也是我国首颗精准农业观测的高分卫星&#xff0c;具有高分辨率、宽覆盖、高质量成像、高效能成像、国产化率高等特…

Mysql数据库:故障分析与配置优化

目录 前言 一、Mysql逻辑架构图 二、Mysql单实例常见故障 1、无法通过套接字连接到本地MySQL服务器 2、用户rootlocalhost访问被拒绝 3、远程连接数据库时连接很慢 4、无法打开以MYI结尾的索引文件 5、超出最大连接错误数量限制 6、连接过多 7、配置文件/etc/my.cnf权…

python 哔哩哔哩视频去水印

使用python 去除视频中的水印 1. 需要安装的包 pip install moviepy pip install numpy pip install opencv_python pip install tqdm 2. 代码 import cv2 import numpy as np import glob from moviepy.editor import VideoFileClip import os from tqdm import tqdm# 判…

2024 年每个程序员都应该尝试的 8 个AI工具

随着人工智能技术的极速发展&#xff0c;新的 AI 工具正以前所未有的速度涌现&#xff0c;为开发者们带来了前所未有的机会和挑战。在这个不断演进的时代&#xff0c;掌握最新的 AI 技术已成为每个程序员的必修课。 在本文中&#xff0c;我们收集了8 个程序员在 2024 年值得尝…

idea 报错 Could not list the contents of folder “ftps

idea 报错 Could not list the contents of folder "ftps 解决方案 这里看到了网上的解决方案&#xff0c;顺便再记录一下。打开 【高级】菜单 - 取消勾选 被动模式。然后点击测试连接&#xff0c;显示连接成功&#xff01; ftp中的主动模式和被动模式 主动模式&…

《HelloGitHub》第 96 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 …

非关系型数据库-----------探索 Redis高可用 与持久化

目录 一、Redis 高可用 1.1什么是高可用 1.2Redis的高可用技术 二、 Redis 持久化 2.1持久化的功能 2.2Redis 提供两种方式进行持久化 三、Redis 持久化之----------RDB 3.1触发条件 3.1.1手动触发 3.1.2自动触发 3.1.3其他自动触发机制 3.2执行流程 3.3启动时加载…

[蓝桥杯练习题]出差

一道DJ题,重要的是隔离时间,把隔离时间加在边权上即可 现实生活的题大多都是无向图建图,需要边的两端点各自上邻接表和相同权重 #include<bits/stdc.h> using namespace std; #define ll long long const int N1005; const int M10005; struct edge{int to;ll w;edge(int…

【JavaSE】一维数组和二维数组详解

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 一维数组 基本语法 初始化 遍历和打印 数组是引用型变量 基本类型变量与引用类型变量的区别 null 数组传参和返回 总结 二维数组 基本语法 初始化 遍历和打印 一维数组…

PID算法调参经验分享

本篇文章旨在分享我对PID算法调节参数的经验&#xff0c;觉得掌握PID调参是一种十分重要的技能&#xff0c;在此记录一下。希望我的分享对你有所帮助。有关PID的一些文章&#xff0c;可以参考以下文章。 PID算法参数调节经验分享-CSDN博客 PID算法详解&#xff08;代码详解篇&a…

缓存和缓存的常用使用场景

想象一下,一家公司在芬兰 Google Cloud 数据中心的服务器上托管一个网站。对于欧洲用户来说,加载可能需要大约 100 毫秒,但对于墨西哥用户来说,加载需要 3-5 秒。幸运的是,有一些策略可以最大限度地减少远程用户的请求延迟。 这些策略称为缓存和内容交付网络 (CDN),它们是…

Git Fork后的仓库内容和原仓库保持一致

Git Fork后的仓库内容和原仓库保持一致 ①Fork原仓库内容到自己仓库 ②将项目内容下载到本地 ③使用git命令获取原仓库内容&#xff0c;将原仓库的最新内容合并到自己的分支上并推送 下面从第三步开始演示~ 这里以码云上的若依项目为演示项目 ③使用git命令获取原仓库内容 …

《Python之路:系统自学指南》

引言 在当今信息时代&#xff0c;编程已经成为一项越来越重要的技能。而Python作为一门功能强大、易学易用的编程语言&#xff0c;受到了越来越多人的青睐。然而&#xff0c;学习Python并不是一蹴而就的事情&#xff0c;尤其是对于没有编程基础的初学者来说&#xff0c;往往需…

matlab/simulink 火电储能一次调频,模糊控制优化储能调频系数分配,WOA鲸鱼算法优化火电储能出力占比,可模拟连续扰动,阶跃扰动

系统频率(阶跃扰动) 储能出力 储能soc对比 系统频率(连续扰动) 可见&#xff0c;鲸鱼算法woa和模糊控制储能更能有限改善频率 这里鲸鱼算法优化的是火储出力占比&#xff0c;模糊控制优化的是储能内部调频控制系数

华为OD机试 - 查找舆情热词(Java 2024 C卷 100分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…