当前位置: 首页 > news >正文

数据结构与算法再探(二)高精度计算

基本知识点:

高精度计算指参与运算的数的范围大大超出了标准数据类型能表示的范围的运算
常用数据范围int(4字节)double(8字节)long int(8字节)
-2147483648 — 2147483647+/- 1.7e +/- 308 (~15 个数字)-9,223,372,036,854,775,808— 9,223,372,036,854,775,807
字符数组用来存放字符的数组称为字符数组,也可以称为字符串,字符串结尾,会自动添加一个 \0 作为字符串结束的标志
进位/溢出

进位:无符号数运算结果超出范围,产生进位标志CF。

溢出:有符号数运算结果超出范围,产生溢出标志OF。

相关操作:

高精度计算也被称作大整数计算,内置类型给的数据范围总会有超出范围的计算,一般处理高精度计算,使用数字数组来表示高精度数字。每一个字符表示数字的一个十进制位,高精度数值计算实际上是一种特别的字符串处理。

转字符数组:

既然使用数字数组就会涉及到数字串转为数字数组,数字位如何存储?转换时是将数字最高位在字符串首(下标小的位置),而后从低位到高位保存各位数字(存储反转的字符串)这么做的原因在于,数字的长度可能发生变化,这样存储的化所有的个位都在下标 [0],所有的十位都在下标 [1]……);同时,加、减、乘的运算一般都从个位开始进行就不会受到影响。

结果输出:

计算之前将字符数组所有元素初始化为0,因为结果是反转存储,输出的时候需要从高位输出,涉及到如果不希望输出前导零的化,需要从最高位开始向下寻找第一个非零位,然后从此处开始输出。输出的终止条件是i>=1而不是i>=0是因为当整个数字等于0时仍希望输出一个字符0。

四则运算实例:

高精度的四则运算重点在于梳理清楚如何处理每一位和进位的规则。

高精度加:

从最低位开始,将两个加数对应位置上的数码相加,并判断是否达到进位 。如果达到,那么处理进位:将更高一位的结果上增加 ,当前位的结果减少 。

高精度减法:

高精度减法,也就是竖式减法,从个位起逐位相减,遇到负的情况则向上一位借 。如果不确定被减数和减数哪个更大,可以先比较一下两个数,如果被减数更小,则先输出负号,再进行更大数字减更小数字的减法运算。

 高精度乘法:

高精度除法:

竖式除法实际上可以看作一个逐次减法的过程。

#include <iostream>
using namespace std;
#define N 102 //高精度位数//数字串转字符数组
int toNum(const string &str, int nums[])
{   int len = str.length();for (int i = 0; i < len; ++i){nums[i] = (str[len - i - 1] - '0');}return len;
}
void add(int pa[],int sizeA,int pb[],int sizeB, int resultC[]) //高精加
{int t = 0; // 进位for (int i = 0; i < sizeA||i<sizeB; ++i){resultC[i] = pa[i] + pb[i] + t;t = resultC[i] / 10;resultC[i] %= 10;}
}
void sub(int pa[], int maxAB,int pb[], int resultC[])//高精度减默认pa>pb
{int  t = 0;//进位for(int i = 0; i <maxAB; ++i){resultC[i] = pa[i] - t - pb[i];t = 0;if(resultC[i] < 0){t = 1;resultC[i] += 10;}}
}
//高精度乘法
void mul(int pa[],int lenA, int pb[],int lenB, int mul[])//高精度乘法
{int i;for(i = 0; i <lenA; ++i){int t = 0;for(int j = 0; j <lenB; ++j){mul[i+j] += pa[i]*pb[j] + t;t = mul[i+j] / 10;mul[i+j] %= 10;}mul[i+lenB] += t;}
}
bool cmp(int a[],int b[],int x,int lenB){//被除数从最高位到第x位,是否大于等于除数if(a[x+lenB]>0) {//如果被除数比除数多一位,返回truereturn true;}for(int i=lenB-1;i>=0;i--){//逐位比较if (a[x+i]<b[i]){//除数大return false;}else if (a[x+i]>b[i]){//被除数大return true;}}return true;
}
void divide(int a[], int b[], int lenA,int lenB,int c[],int d[])//r:商 x:余数 
{int LA,LB;for (LA=lenA; LA >0; --LA)if (a[LA-1] != 0) break;for (LB = lenB; LB >0; --LB)if (b[LB-1] != 0) break;if (LB == 0) {cout<<"除数不可以为0";return;}  // 除数不能为零// d 是被除数的剩余部分,算法结束后自然成为余数for (int i = 0; i < LA; ++i) d[i] = a[i];for(int i=LA-LB;i>=0;--i){while(cmp(d,b,i,LB)){//够减c[i]++;//商加1for(int j=0;j<LB;++j){//逐位相减if (d[i+j]>=b[j]){//够减d[i+j]-=b[j];//直接减}else{//不够减d[i+j+1]--;//借位d[i+j]+=10-b[j];//加10再减}}}} 
}
void show(int tmp[]){
int i;for (i = N - 1; i >= 1; --i)if (tmp[i] != 0)break;for (; i >= 0; --i)cout << tmp[i];cout<<endl;
}
int main()
{int a[N]={}, b[N]={}, c[N]={},rmul[2*N]={},d[N]={};string s = "2000";string s1 = "100";int lenA=toNum(s,a);int lenB=toNum(s1,b);// add(a,lenA,b,lenB,c);// cout<<"-add-result ";// show(c);// cout<<"-mul-result ";// mul(a, lenA,b,lenB, rmul);// show(rmul);// cout<<"-sub-result ";// int i;// if(lenA>lenB||(lenA==lenB&&s>=s1)){//     sub(a,lenA,b,c);//     show(c);// }else{//     sub(b,lenB,a,c);//b>a输出-//     cout<<"-";//     show(c);// }divide(a,b,lenA,lenB,c,d);cout<<"-divide-quotient ";show(c);cout<<"-divide-remainder ";show(d);return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • ActiveMQ指南
  • SpringBoot项目目录介绍(SpringBoot学2)
  • pycharm中opencv-python和opencv-contrib安装
  • 【XR】SDK的接口规划与设计
  • K8S对接Ceph分布式存储
  • apache服务器的配置(服务名httpd,端口80 , 443)
  • Ubuntu安装交叉编译工具链(gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu)
  • 中文乱码解决方案
  • R语言论文插图模板第8期—特征渲染的散点图
  • YoloV8改进策略:主干网络改进|CAS-ViT在YoloV8中的创新应用与显著性能提升
  • 独立开发者系列(45)——PHP的时间处理详解
  • (160)时序收敛--->(10)时序收敛十
  • 单链表——相交链表
  • 安美数字酒店宽带运营系统-任意文件读取
  • xss-labs通关攻略 16-20关
  • 08.Android之View事件问题
  • 0x05 Python数据分析,Anaconda八斩刀
  • android图片蒙层
  • angular2 简述
  • javascript从右向左截取指定位数字符的3种方法
  • Js基础知识(四) - js运行原理与机制
  • spring + angular 实现导出excel
  • SpringBoot几种定时任务的实现方式
  • SpringCloud集成分布式事务LCN (一)
  • 从零开始的无人驾驶 1
  • 和 || 运算
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 使用API自动生成工具优化前端工作流
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • #C++ 智能指针 std::unique_ptr 、std::shared_ptr 和 std::weak_ptr
  • #pragma 指令
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (¥1011)-(一千零一拾一元整)输出
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (苍穹外卖)day03菜品管理
  • (动态规划)5. 最长回文子串 java解决
  • (分享)自己整理的一些简单awk实用语句
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一) 初入MySQL 【认识和部署】
  • (一)Dubbo快速入门、介绍、使用
  • (转)大型网站的系统架构
  • (转)使用VMware vSphere标准交换机设置网络连接
  • .net 调用php,php 调用.net com组件 --
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .net反混淆脱壳工具de4dot的使用
  • .NET开发者必备的11款免费工具
  • .NET应用UI框架DevExpress XAF v24.1 - 可用性进一步增强
  • @TableId注解详细介绍 mybaits 实体类主键注解
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具
  • [04] Android逐帧动画(一)
  • [20170728]oracle保留字.txt
  • [ACM独立出版] 2024年虚拟现实、图像和信号处理国际学术会议(VRISP 2024,8月2日-4)
  • [AutoSar]BSW_OS 01 priority ceiling protocol(PCP)
  • [BeginCTF]真龙之力