大一小白尝试高精度除高精度

引言

笔者是一位大一学生,在做题的过程中接触到了高精度除法,写下这篇博客帮助理清思路。希望这篇博客能够帮助到更多刚接触C语言的同学们。如果文中有错误,欢迎指正。

一、什么是高精度除法

高精度除法就是对于普通数据类型无法表示的大整数进行除法运算。

二、为什么需要高精度除法

在C语言中,常用的数据类型有int, long long, double等,但是这些数据类型的大小有限,当输入的数据过大,这些数据类型就无法实现其功能,强行使用可能会出现错误。在这种情况下,我们需要高精度除法来完成运算。

三、高精度除法的实现方式

思路

参考高精度乘法的思路,首先我们知道电脑笨笨的,其次我们知道可以回到小学寻求答案,于是高精度除法的实现思路就十分清晰了。那就是模拟手动运算除法的方式,也就是说,我们要通过竖式除法运算达到高精度运算的目的。

数据类型

与高精度乘法相类似的,我们选择字符串来存储很大很大的一些整数(真是太可恶了!)

竖式除法复习

这里我们只看整数的除法法则

1)从被除数的高位起,先看除数有几位,再用除数试除被除数的前几位,如果它比除数,再试除多一位数;

2)除到被除数的哪一位,就在那一位上面写上商;

3)每次除后余下的数必须比除数小

实现步骤

1.输入
2.试除(比大小移位)
3.结束
4.输出

准备工作

void High_Precision_Division(char c_dividend[], char c_divisor[], char c_quotient[]) {int i;int i_dividend[Number_Size];//被除数int i_divisor[Number_Size];//除数int i_quotient[Number_Size];//商char temp_answer[Number_Size];int start;int flag;int length_temp_answer;int length_divisor = strlen(c_divisor);int length_dividend = strlen(c_dividend);memset(c_quotient, 0, length_quotient);memset(i_dividend, 0, sizeof(i_dividend));memset(i_divisor, 0, sizeof(i_divisor));memset(i_quotient, 0, sizeof(i_quotient));memset(temp_answer, 0, sizeof(temp_answer));//完成初始化if (Size_Comparison(c_dividend, length_dividend, c_divisor, length_divisor) < 0) {c_quotient[0] = '0';return;}start = 0;
}

进行试除

我们知道,试除的过程实际上就是比大小,如果不够大则移动一位,如果够大则算出商。为了方便,我们这里引入一个比大小的函数。

int Size_Comparison(char str_1[], int length_1, char str_2[], int length_2) {int i;if (length_1 < length_2) {return -1;}else if (length_1 > length_2) {return 1;}else {for (i = 0; i < length_1; i++) {if (str_1[i] < str_2[i]) {return -1;}else if (str_1[i] > str_2[i]) {return 1;}}return 0;}
}

这个函数传入两个char*,两个int,若返回-1则第一个小,返回1则第一个大,返回0则相等。
现在为了能够算出商,我们需要引入高精度减法的函数。试除的数能减几次,商就是几。

 //start代表的是被除数试除的起始位置while (length_dividend - start >= length_divisor) {if (length_dividend - start == length_divisor && Size_Comparison(&c_dividend[start], length_divisor, c_divisor, length_divisor) < 0) {break;}//如果剩下的数不够除了(长度相等而小于)就退出循环if (Size_Comparison(&c_dividend[start], length_divisor, c_divisor, length_divisor) < 0) {//长度足够但是同位数时不够,就向后借一位i_quotient[start + length_divisor]++;//对应位置商加一High_Precision_Subtraction(&c_dividend[start], length_divisor + 1, c_divisor, length_divisor, temp_answer, 1, &flag);//从对应位置减去除数length_temp_answer = strlen(temp_answer);//temp_answer里面存储的是差memset(&c_dividend[start], 0, sizeof(char) * (length_divisor + 1));start = start + length_divisor + 1 - length_temp_answer;for (i = 0; i < length_temp_answer; i++) {c_dividend[i + start] = temp_answer[i];}//这一段完成的是拷贝,当然也可以用函数,之后会进行优化memset(temp_answer, 0, sizeof(temp_answer));}else {//与上一段同理,长度相同时可以继续,就直接作差i_quotient[start + length_divisor - 1]++;High_Precision_Subtraction(&c_dividend[start], length_divisor, c_divisor, length_divisor, temp_answer, 1, &flag);length_temp_answer = strlen(temp_answer);memset(&c_dividend[start], 0, sizeof(char) * length_divisor);start = start + length_divisor - length_temp_answer;for (i = 0; i < length_temp_answer; i++) {c_dividend[i + start] = temp_answer[i];}memset(temp_answer, 0, sizeof(temp_answer));}}//完成除的过程

处理商

首先将多余的0除去,在这里是前导零,然后转换回字符串

 for (i = 0; i < length_dividend; i++) {if (i_quotient[i]) {start = i;break;}}length_quotient = length_dividend - start;for (i = start; i < length_dividend; i++) {c_quotient[i - start] = i_quotient[i] + '0';}//处理商并输出

全部代码

void High_Precision_Division(char c_dividend[], char c_divisor[], char c_quotient[], int length_quotient) {int i;int i_dividend[Number_Size];//被除数int i_divisor[Number_Size];//除数int i_quotient[Number_Size];//商char temp_answer[Number_Size];int start;int flag;int length_temp_answer;int length_divisor = strlen(c_divisor);int length_dividend = strlen(c_dividend);memset(c_quotient, 0, length_quotient);memset(i_dividend, 0, sizeof(i_dividend));memset(i_divisor, 0, sizeof(i_divisor));memset(i_quotient, 0, sizeof(i_quotient));memset(temp_answer, 0, sizeof(temp_answer));//完成初始化if (Size_Comparison(c_dividend, length_dividend, c_divisor, length_divisor) < 0) {c_quotient[0] = '0';return;}start = 0;while (length_dividend - start >= length_divisor) {if (length_dividend - start == length_divisor && Size_Comparison(&c_dividend[start], length_divisor, c_divisor, length_divisor) < 0) {//如果剩下的数不够除了就退出循环break;}if (Size_Comparison(&c_dividend[start], length_divisor, c_divisor, length_divisor) < 0) {//长度足够但是同位数时不够,就向后借一位i_quotient[start + length_divisor]++;//对应位置商加一High_Precision_Subtraction(&c_dividend[start], length_divisor + 1, c_divisor, length_divisor, temp_answer, 1, &flag);length_temp_answer = strlen(temp_answer);memset(&c_dividend[start], 0, sizeof(char) * (length_divisor + 1));start = start + length_divisor + 1 - length_temp_answer;for (i = 0; i < length_temp_answer; i++) {c_dividend[i + start] = temp_answer[i];}memset(temp_answer, 0, sizeof(temp_answer));}else {i_quotient[start + length_divisor - 1]++;High_Precision_Subtraction(&c_dividend[start], length_divisor, c_divisor, length_divisor, temp_answer, 1, &flag);length_temp_answer = strlen(temp_answer);memset(&c_dividend[start], 0, sizeof(char) * length_divisor);start = start + length_divisor - length_temp_answer;for (i = 0; i < length_temp_answer; i++) {c_dividend[i + start] = temp_answer[i];}memset(temp_answer, 0, sizeof(temp_answer));}}//完成除的过程for (i = 0; i < length_dividend; i++) {if (i_quotient[i]) {start = i;break;}}length_quotient = length_dividend - start;for (i = start; i < length_dividend; i++) {c_quotient[i - start] = i_quotient[i] + '0';}//处理商并输出return;
}

四、结语

这个函数使用的实际上是减法,因此在时间复杂度上是非常高的,处理很小的除数除很大的被除数十分容易超时,后续会对除数这一块进行优化。十分感谢各位的阅读!

C语言实现高精度除高精度相关推荐

  1. 高精度算法——高精度加法

    说明: 高精度可以说除了排序算法以外接触到的第一个算法了,反正我是这样的,高精度主要是用在c/c++,因为Python 是默认无限大的,所以不需要用高精度,JAVA是有库可以调用也是不需要用高精度,其 ...

  2. 高精度算法——高精度减法

    介绍: 高精度减法也同加法一样,也是用于位数太大的运算,给你一个十几位的数你可能会做直接开个long long 的数据类型就解决了,但是给你一个100位的呢,1000位的呢,开long long 也不 ...

  3. 高精度之高精度除法(高精除以高精)

    好像NOIP并不会用到,但是作为强迫症的我还是坚持学了.高精度除以高精度我所知道的有两个思路: 手动模拟法 还是手动模拟除法过程,但是注意在截取了被除数的正确片段之后应该试商,即枚举k从1到9看当k等 ...

  4. C语言长精度除法,高精度除法小数点位数

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 题目描述 a/b. a,b为integer范围内的整数. 求a/b的前n位小数商. 输入 a b n 输出 一行数字 样例输入97 61 50样例输出1. ...

  5. c语言除出小数点,高精度除法小数点位数

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 题目描述 a/b. a,b为integer范围内的整数. 求a/b的前n位小数商. 输入 a b n 输出 一行数字 样例输入97 61 50样例输出1. ...

  6. 国王游戏(贪心 + 高精度乘法 + 高精度除法 + 高精度比较大小)

    题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏. 首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数. 然后,让这 n 位大臣排成一排,国王站在队伍 ...

  7. 【高精度】高精度除以高精度 C++题解

    题目描述: 输入两个正整数,求它们的商和余数. 分析: 高精度除以高精是用减法模拟除法,对被除数的每一位都减去除数,一直减到当前位置的数字小于除数. 代码: #include<bits/stdc ...

  8. 高精度加法 高精度减法 高度除法 高精度乘法 方法总结

    一.引言 对于数字的储存,用实数类型总会有一些不足,比如: 使用int 只能最多存储4个字节,范围也就是2的32次方: 使用double 只能最多储存8字节,就是2的64次方: 如果数字超过这个限制, ...

  9. matlab高精度工具箱,高精度捷联惯性导航系统Matlab工具箱

    [实例简介] 高精度捷联惯性导航系统Matlab工具箱 [实例截图] [核心代码] psins140603 └── psins140603 ├── base │   ├── align │   │   ...

最新文章

  1. TOP10全球ICT技术发展趋势
  2. 在 CentOS 7 中安装并使用自动化工具 Ansible
  3. LeetCode Shortest Unsorted Continuous Subarray
  4. 简单shell 学习
  5. flatmap_flatMap()与concatMap()与concatMapEager()– RxJava常见问题解答
  6. SpringBoot中的Tomcat是如何启动的
  7. Mybatis使用之 Caused by: org.apache.ibatis.type.TypeException: Could not resolve type alias‘User’
  8. 【Linux】du命令用法详解
  9. 类似于QQ游戏百万人同时在线的服务器架构实现
  10. jvm内存参数配置_JVM内存结构和Java内存模型
  11. 6.苹果官方鼠标移动速度慢问题解决(Magic Mouse)
  12. word——VBA编程
  13. Python利用Reportlab生成PDF文档
  14. XSS跨站脚本攻击和预防措施
  15. echarts 柱状图颜色及渐变色设置
  16. Mask R-CNN网络详解
  17. 自然人股东分红必须要缴纳20%个税吗?有三种真不用
  18. vmware开启虚拟机时虚拟机黑屏的解决办法
  19. [Unity Native Container] 自定义Native Container [第 1 部分]:基础知识
  20. 给Flutter中的Widget设置透明度

热门文章

  1. Javafx顶级容器Stage(舞台)
  2. 转炉炼钢计算机仿真实验报告,转炉侧吹熔炼水模型计算机仿真实验-计算机仿真论文-计算机论文(8页)-原创力文档...
  3. 刚参加完阿里面试:一面+二面+三面+HR四面,我的复盘经验总结!
  4. 玩转树莓派 一、为你的树莓派烧录系统镜像
  5. 人工智能学习笔记——KL散度
  6. 特警把那盅犯形容的汝么厉害
  7. OpenCV实战——角度测量
  8. 雨伞16骨好还是24骨好_伞骨什么材质好 晴雨伞骨数越多越好吗
  9. 家庭NAS服务器(1)服务器的配置与选择
  10. Zotero使用GB/T7714 2005模板插入参考文献出现 作者名全部大写问题、et al.变成汉字‘等‘、多出参考文章的doi 问题 的解决方案