前言

这种类型,在做题过程中多为观察所给数据可能造成的大小来选择是否使用。

属于模板类型,学习者理解其格式并记住大致框架即可熟练应用。


一、什么是大整数(高精度)

想知道什么是大整数,不如换一个解释的方法:什么时候需要用到大整数?

众所周知,int类型的范围是-2147483648~2147483647。long long类型的范围是 -2^63 ~ (2^63)-1。那当题目需要用到或需要输出比long long类型的范围还要大的数字时,我们是不是就不能用常规办法去接收这些数字了。这个时候使用大整数就可以解决上述问题。即解决接收超出long long范围数字的问题。

二、大整数的存储

原理很简单,使用数组。

例如定义Int类型数组d[1000],那么这个数组中的每一位就代表存放整数的每一位。比如将数字123456存储,则有d[0] = 6,d[1] = 5,d[2] = 4,d[3] = 3,d[4] = 2,d[5] = 1。整数的高位存在数组的高位,整数的低位存储在数组的低位。(为了契合加减乘除的思维)

这时候会产生一个需要注意的问题:把整数通过%s或者itoa的方式变成字符串的时候,一开始是逆位存储的,即d[0] = 1...,因此读入的之后需要在另存为至d[i]数组的时候反转一下

为了方便随时获取大整数的长度,一般定义len来记录长度,并与d数组组合成结构体。

struct bign{int d[1000];int len;
};

bign是big number的缩写。

一般输入大整数时,都是先用字符串读入,然后再把字符串另存为至bign结构体。由于使用char数组进行读入时,整数高位会变成数组地位,整数的地位会变成数组的高位。因此为了让整数在bign中是顺位存储,需要让字符串倒着赋值给d[]数组。

bign change(char str[])//将整数转换为bign
{bign a;a.len = strlen(str);//bign的长度就是字符串的长度for(int i = 0; i < a.len; i++){a.d[i] = str[a.len-i-1] - '0';}return a;
}

 如果要比较两个bign变量的大小,也很简单:先判断len大小,若不相等,长的为大,若相等,则从高位至低位逐个比较,直到某一位不等,则可以判断两者大小。

int compare(bign a,bign b)
{if(a.len > b.len) return 1;//a大 else if(a.len < b.len) return -1;//a小 else{for(int i = a.len - 1; i >= 0; i--)//从高位到低位开始比较 {if(a.d[i] > b.d[i]) return 1;//只要有一位a大,则a大 else if(a.d[i] < b.d[i]) return -1;//只要有一位a小,则a小 }return 0;//两位相等 }
}

最后如果需要输出bign变量的值,遍历一遍就可以实现了。

void print(bign a)
{for(int i = a.len - 1; i >= 0; i--) {printf("%d",a.d[i]);}printf("\n");
}

三、大整数的四则运算

1、高精度加法

加法实现方式与我们以前学到的加法一样。对于某一位的运算:我们将该位上的两个数字与进位相加,得到的结果取个位数作为该结果,十位数作为新的进位。

bign add(bign a,bign b)
{bign c;int carry = 0; //carry是进位for(int i = 0; i < a.len || i < b.len; i++) //以较长的为界限 {      int temp = a.d[i] + b.d[i] + carry;      //两个对应位与进位相加 c.d[c.len++] = temp%10;     //个位数为该位的结果 carry = temp/10;   //十位数为新的进位 }if(carry != 0) //如果最后进位不为0,则直接赋给结果的最高位  {c.d[c.len++] = carry;       }return c;
}

这里有一点需要注意,这样写法的条件是两个对象都是非负整数。如果有一方是负的,可以在转换到数组这一步时去掉符号,再使用高精度减法;如果两个都是负的,都去掉负号后采用高精度加法,最后负号加回去即可。

2、 高精度减法

通过对减法步骤的拆分可以得到一个简练的步骤:对某一位,比较被减位和减位,如果不够减,则令被减位的高位减1,被减位加10再进行减法;如果够减,直接减。最后需要注意减法后高位可能有多余的0,要去除他们,但也要保证结果至少有一位数

bign sub(bign a,bign b) //a - b
{bign c;for(int i = 0; i < a.len || i < b.len; i++) //以较长的为界限{     if(a.d[i] < b.d[i]) //不够减 {      a.d[i + 1]--;  //向高位借位 a.d[i] += 10;     //向前位借10  }c.d[c.len++] = a.d[i] - b.d[i];       //减法结果为当前位 }while(c.len - 1 >= 1 && c.d[c.len - 1] == 0) {c.len--;    //去除高位的0,同时至少保留一位最低位 } return c;
}

最后需要指出,使用sub函数前要比较两个数的大小,如果被减数小于减数,需要交换两个变量,然后输出负号,再用sub函数。

3、高精度与低精度的乘法

这里所谓的低精度就是基本数据类型存储的数据,如int。这里就是bign与int的乘法。

对某一位来说是这样的步骤:取bign的某位与int型整体相乘,再与进位相加,所得结果的个位数作为该结果,高位部分作为新的进位。

bign multi(bign a,int b)
{bign c;int carry = 0; //进位for(int i = 0; i < a.len; i++) {int temp = a.d[i] * b + carry;c.d[c.len++] = temp % 10;      //个位作为该结果carry = temp / 10;    //高位部分作为新的进位 } while(carry != 0) //和加法不一样,乘法的进位可能不止一位,因此用while { c.d[c.len++] = carry % 10;carry /= 10;} return c;
}

另外,如果a和b中存在负数,需要先记录下负号,然后取他们的绝对值带入函数。

4、高精度与低精度的除法

归纳其中一位的步骤:上一步的余数乘以10加上该步的位,得到该步临时的被除数,将其与除数比较;如果不够除,则该位的商为0;如果够除,则商即为对应的商,余数即为对应的余数。最后一步要注意减法后高位可能有多余的0,要去除他们,但也要保证结果至少有一位数。

bign divide(bign a,int b,int& r) //r为余数
{   bign c;c.len = a.len;//被除数的每一位和商的每一位是一一对应的,因此先令长度相等 for(int i = a.len - 1; i >= 0; i--)  //从高位开始 {  r = r * 10 + a.d[i];     //和上一位遗留的余数组合if(r < b) c.d[i] = 0;      //不够除,该位为0 else //够除 {       c.d[i] = r / b;    //商r = r % b;      //获得新的余数 }}while(c.len - 1 >= 1 && c.d[c.len - 1] == 0) { c.len--; //去除高位的0,同时至少保留一位最低位 }return c;
}

考虑到很多题目会要求得到余数,因此把余数写成引用的形式直接作为参数传入,或者也可以把余数设成全局变量。

大整数运算(高精度运算)C/C++相关推荐

  1. c语言任意两个整数相减_大整数加减运算的C语言实现

    大整数加减运算的 C 语言实现 一 . 问题提出培训老师给出一个题目:用 C 语言实现一 个大整数计算器.初步要求支持大整数的加.减运算,例如 8888888888888+1112=888888889 ...

  2. 大整数的加减乘除运算

    本关任务: 掌握大整数的基本思想,并运用大整数的基本运算计算出常规整数n的阶乘,然后统计大整数n!中数字0的个数. 相关知识 为了完成本关任务,你需要掌握:1.大整数的思想,2.大整数加法,3.大整数 ...

  3. 基础算法一:大整数模积运算

    文章目录 一.要求 二.实现原理 三.示例代码 四.测试用例 一.要求 只能有加减位运算 支持大数(64位)模积运算(a * b mod m) 处理模加中的溢出问题 (如果 a + b = c 溢出, ...

  4. 高精度算法(大整数的加减乘除运算)

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

  5. C++ 大整数运算 高精度除法

    前言 这篇文章主要是对于大整数类的设计过程中,如何实现并改进长除法(模拟竖式法)的一个总结. 高精度除法的分类和比较 虽然有些文章在讨论大整数的除法运算时,喜欢分成高精度除以高精度和高精度除以低精度( ...

  6. 【密码学】RSA的大整数雏形

    2019.11.23: 这个代码一开始采用的是如<算法笔记>上等PAT中的类似题目将十进制数字转换为数组大整数(也是十进制形式). 但是这种想法在后来实现加密的时候快速积出现了严重的弊端, ...

  7. 求一个整数的权重 c语言,Code Kata:大整数四则运算—乘法 javascript实现

    上周练习了加减法,今天练习大整数的乘法运算. 采取的方式同样为竖式计算,每一位相乘后相加. 乘法函数: 异符号相乘时结果为负数,0乘任何数都为0 需要调用加法函数 因为输入输出的为字符串,需要去除字符 ...

  8. Date_Calendar_SimpleDateFormat_大浮点数和大整数

    文章目录 Date类 Calendar类 SimpleDateFormat BigInteger 大整数 BigDecimal 大浮点数 Date类 java.util包下的类 public clas ...

  9. 山东大学软件工程应用与实践——GMSSL开源库(十)——重要的大整数

    2021SC@SDUSC 文章标题 BIGNUM的结构 大整数的加减法(绝对值加减) 绝对值加减 带符号加减 大整数的乘法 经典乘法 递归和comba乘法 小结 无论是SM2.SM9等国密算法还是以R ...

最新文章

  1. ASP.NET -- 缓存技术(1)
  2. php编写函数6,编写自己的PHP扩展函数
  3. http://www.cnblogs.com/qtqq/p/5271164.html
  4. spring源码解析五
  5. node.js初步探究
  6. SIGIR 2021|重新思考Attention在CTR预估中作用
  7. php 文件名汉字utf8,php utf8编码上传中文文件名出现乱码_PHP教程
  8. 怎么画正五边形步骤_悄悄告诉你们:一种没有美术基础,也能画好画的方法
  9. win10家庭版没有device guard_普通用户选择哪个Win10系统版本?家庭版与专业版的对比介绍...
  10. 记住要重置线程上下文类加载器
  11. 今天的解放过后的蜡笔小新
  12. CCNA学习总结—OSPF协议—OSPF协议原理
  13. 《沉浸式线性代数》完整版正式发布,全交互式体验
  14. HoloLens开发手记 - Unity之语音输入
  15. back to wuxi
  16. workstation服务重启后自动停止,需要手动启动,解决方案
  17. 光电信息科学与工程学c语言吗,光电信息科学与工程是热门吗?本文讲给你讲个透彻...
  18. 假币问题 (n枚硬币+未知轻重+DFS)
  19. 腾讯网页登陆的加密机制
  20. CVX工具下载及测试

热门文章

  1. 传日本NTT Data在竞购戴尔Perot Systems
  2. Soot 静态分析框架(七)模块分析
  3. python 升级setuptools_Python深入:setuptools进阶
  4. Android的LeakCanary的原理分析
  5. Postgres时间字段设置默认值
  6. TMS320F28335时钟(1) -----PLL倍频器的初始化详解
  7. grub rescue修复引导
  8. STM32利用定时器1控制LED闪烁
  9. 条码标签打印软件导入Excel批量打印标签
  10. Win10正确安装Ganache方法