巨大数

  • 什么是巨大数
    • 目的
  • 巨大数的加法
    • 巨大数的存储
    • 万进制
    • 微易码补码
  • 巨大数的减法
  • 巨大数的乘法
  • 总结

什么是巨大数

巨大数其实就是有效数字位很大,可表示数的大小超过了int 的表示范围:[-217483648,2147483647],虽然float、double类型可表示的数的范围很大,分别为:3.4E-38~3.4E+38、1.7E-308~1.7E+308。但是它们的有效数字位却不大,分别为:6 – 7位、5 – 16位。这时我们需要一个可以表示很大有效数字位的数—巨大数

目的

为了解决超出计算机可表示范围数据的存储以及运算,如果按照平常的计算方法便会无能为力,这时,便需要一种可以解决更大位数计算的方法,也就是巨大数四则运算所存在的意义。而且我们的巨大数还可以为小数,因此起到增加计算精度的作用,本篇文章将重点讲述巨大数的存储以及四则运算。

巨大数的加法

巨大数的存储

上面说到,巨大数会超过int、float、double的表示范围,所以我们不能用它们来存储巨大数,这里我们用字符串,也就是定义一个char类型的数组,来存储巨大数,然后将它转化为整型量,存储到int类型的数组中(采用高高低低原则数组的高位存储的是数据的高位,数组的低位存储的是数据的低位),即数据的个十百千位的四个数,存储到数组的第一个元素上,再参与运算。

巨大数结构体

typedef struct HUGE_NUMBER
{boolean sign; //存储巨大数符号int *data; //存储巨大数的数字int count; //数组元素的个数int length; //巨大数位数int pow; //权重,多少位小数
}HUGE_NUMBER;

万进制

这里我们引入万进制,主要是为了效率问题,万进制,顾名思义,以万进1,其实万进制存储也就是用int类型的数组,四位一存,然后四位四位的进行运算,和我们所理解的十进制其实大同小异。如果,万进制运算效率高,那么我们为什仫不采用十万进制呢? 这样运算效率会更高,因为万进制一个位存储的最大9999(大于9999要进位),在做乘法计算时即使9999乘以9999,依然可以暂时放在这个位上,因为每一个位都是int类型的,整体是一个int类型的数组,最后再做统一处理。

微易码补码

这是巨大数的核心技术,相当厉害。

  1. 微易码补码的原理,类似计算机中原码和补码的转化:正数,原码 = 补码;负数,补码 = 原码按位取反,末位加1。微易码补码的原理:正数,等于其本身;负数,9999 - 这个数的绝对值。
  2. 为什么要引入《微易码补码》?在进行加减法运算时,减法可以转化为加法运算,那么减法其实就是加法,再进行加法过程中,运算数是带符号位的,有可能是负数。所以我们引入微易码补码就是为了减少因为负数而引起的复杂运算,这样简化运算。
  3. 上面简单的举了个例子,来说明微易码补码,下面将详细介绍微易码补码的神奇之处:



  4. 加法运算的代码:
void addHUGE(HUGE_NUMBER *hn1, HUGE_NUMBER *hn2, HUGE_NUMBER *result)
{int carry = 0;int sum;int i;result->count = hn1->count > hn2->count ? (hn1->count + 1): (hn2->count + 1);  //运算结果存在着进位的可能,所以要多申请一个空间;//若不进位,正数,这个空间将会补 0000 ;负数,这个空间将会补 9999。//建议可以变量跟踪一下。result->data = (int *)calloc(sizeof(int), result->count);for (i = 0; i < result->count; i++) {if (i >= hn1->count) {hn1->data[i] = 0;}if (i >= hn2->count) {hn2->data[i] = 0;}sum = getMecCode(hn1->data[i], hn1->sign) + getMecCode(hn2->data[i], hn2->sign) + carry;carry = sum / 10000;sum = sum % 10000;result->data[i] = sum;}result->data[0] += carry; //有进位情况下,运算的结果和正确结果相差1, 这里加上进位。if (hn1->sign ^ hn2->sign ^ carry) { //得到运算结果的符号,若为负号,要将补码转化。result->sign = NEGATIVE;for (i = 0; i < result->count; i++) {result->data[i] = getMecCode(result->data[i], result->sign);}}else {result->sign = POSITIVE;}
}
int getMecCode(int data, char sign)
{return ((sign == 1) ? (9999 - data) : data);
}

巨大数的减法

巨大数的减法和加法一样。减法就是将一个运算数取相反数,再调用加法函数,就ok了。

void subHUGE(HUGE_NUMBER *hn1, HUGE_NUMBER *hn2, HUGE_NUMBER *result)
{hn2->sign = (hn2->sign == 1) ? 0 : 1;addHUGE(hn1, hn2, result);hn2->sign = (hn2->sign == 1) ? 0 : 1;
}

巨大数的乘法

巨大数的乘法比较简单,它不需要用到微易码补码,只需要用万进制存储,就OK了。

四位一存,每次相错4位。

void mulHUGE(HUGE_NUMBER *hn1, HUGE_NUMBER *hn2, HUGE_NUMBER *result)
{int carry = 0;int sum;int i;int j;int t = 0;result->count = (hn1->count > hn2->count ? hn1->count : hn2->count) * 2;result->data = (int *)calloc(sizeof(int), result->count);result->sign = hn1->sign ^ hn2->sign;for (i = 0; i < hn1->count; i++) {t = i;for (j = 0; j <= hn2->count; j++) {if (j == hn2->count) {hn2->data[j] = 0;}sum = hn1->data[i] * hn2->data[j] + carry;carry = sum / 10000;sum = sum % 10000;result->data[t] += sum; //错位相加carry += result->data[t] / 10000; //保证每个数组元素中只存储四位result->data[t] = result->data[t] % 10000;t++;}}
}

运行结果:

总结

首先,感谢铁血教主的指导,在这个巨大数项目中,对于万进制和微易码补码的运用,我感到很凶悍,这些方法确实让人感到新颖,教主nb~。同时,在我完成过程中,觉得一定要注意“手工过程”和“变量跟踪”,许多错误在编写时,是很难发现的。所以,在编写前,先进行“手工过程”,而且一定要充足,这样整理和开阔你的思路,有时候你敲几个小时的代码,都不如半个小时的手工过程。同时和同学一起进行讨论也是一种开阔思维的方法。

【C语言数据结构与算法的应用4】巨大数----加减乘运算(万进制和Mec补码的应用)相关推荐

  1. 【数据结构与算法】之深入解析“分数加减运算”的求解思路与算法示例

    一.题目要求 给定一个表示分数加减运算的字符串 expression,你需要返回一个字符串形式的计算结果. 这个结果应该是不可约分的分数,即最简分数. 如果最终结果是一个整数,例如 2,你需要将它转换 ...

  2. 每天一算法(一)——用链表实现加减乘运算

    用链表实现加减乘运算 // resultW.cpp : 定义控制台应用程序的入口点. #include "F:\HU\resultW\resultW\stdafx.h" #incl ...

  3. c语言数据结构插入算法说明,C语言数据结构插入算法

    C语言数据结构插入算法 C语言数据结构插入算法 C语言数据结构 数据结构学习 ->是二目运算符 p->a 引用了指针p指向的结构体的成员a. 整合 void unionL(List *La ...

  4. Go语言-数据结构与算法

    go语言之专业数据结构与算法 3.golang实现数组结构 code\ArrayList\ArrayList.go package ArrayListimport ("errors" ...

  5. 【C语言-数据结构与算法】-哈夫曼压缩解压缩-终局-如何做一个自己独有的压缩软件

    哈夫曼压缩&解压缩 Ⅰ 前言 Ⅱ 需求分析&主函数带参的应用 A. 需求分析 B. 压缩部分 B. 解压缩部分 Ⅲ 哈夫曼压缩 A. 代码分析 B. 从文件中读取内容生成频度表 C. ...

  6. 黑马程序员 C语言数据结构与算法之线性表(链表/栈/队列/顺序表)

    C语言 链表基础知识清晰讲解(黑马) 讲的蛮好,就是音质不太好,有时听不清讲的啥! [黑马]数据结构与算法之线性表(链表/栈/队列/顺序表)[配套源码 嘛蛋,看错了,这是java的... 文章目录 链 ...

  7. C语言 数据结构与算法 一

    2019独角兽企业重金招聘Python工程师标准>>> 今天在看数据结构与算法的练习题,结果发现第一道就看不懂. 举例如下 有一序列 {1,2,-96,12,-5,1,12,-12} ...

  8. 输入一个数寻找丑数C语言,数据结构与算法试题80道.doc

    数据结构与算法试题80道 由于这些题,实在太火了.所以,应广大网友建议要求,在此把之前已整理公布的前80题, 现在,一次性分享出来.此也算是前80题第一次集体亮相. 此些题,已有上万人,看到或见识到, ...

  9. C语言数据结构与算法

    该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/105088894 数 ...

最新文章

  1. 6个值得推荐的Android开源框架简介
  2. 手机相机自动对焦的原理
  3. python soup findall 第几个元素_python – 如何在BeautifulSoup中获取所有父标签的列表?...
  4. Windows vs Linux:\r\n 与 \r
  5. Gartner:缺乏技术人才将影响企业数字化转型
  6. @cacheable 是否缓存成功_缓存策略:如何使用缓存来减少磁盘IO?
  7. java 分贝_java11教程--jhsdb命令
  8. 如何成为“10倍效率”开发者
  9. python ocr 文字识别软件,Python文字截图识别OCR工具实例解析
  10. COLING 2020 | 一种从科学文献中提取关键词的基于自蒸馏的联合学习方法
  11. 洛谷P2024 [NOI2001]食物链
  12. CKEditor、UEditor富文本编辑器原理(CSDN编辑器原理)
  13. Basic knowledge about python
  14. 一般论文发表流程有哪些
  15. Qt 之显示网络图片
  16. RD Client远程控制PC
  17. 文件管理学习:从百度网盘搬家onedrive测评
  18. 有趣的java代码_求一些有趣的java小程序?
  19. JavaScript通过键盘方向键控制盒子移动
  20. python 通过ftp自动 上传指定excel文件

热门文章

  1. 如何利用 C# 爬取「猫眼电影:国内票房榜」及对应影片信息!
  2. 简单的基于交换机迁移的SDN控制器负载均衡实验
  3. ROS 初学入门学习及资源推荐
  4. Word文档怎样翻译?Word文档翻译方法大分享
  5. 编程的宗派(OOP与FP孰优孰劣)--王垠
  6. CentOS 基础命令 III
  7. J9说数字科普为何DeFi永不消亡
  8. 密码学编程基础——换位加密
  9. 超七成阅读APP都借百度语音技术促用户增长
  10. iframe预览文件