一、简介

众所周知,C语言中INT类型是有限制,不能进行超过其范围的运算,而如果采用float类型进行运算,由于float在内存中特殊的存储形式,又失去了计算的进度。要解决整个问题,一种解决方法是通过字符串数组实现数据的存储,然后实现它们之间四则运算的函数。

二、数据结构

为了实现字符数组之间的运算,要考虑数值的正负性,数字的长度以及具体存储的数字

  1. typedef struct num{
  2. int len; //数值长度
  3. char symbol; //数字正负形
  4. int number[LEN]; //数组
  5. }NUM,*SNUM;

三、函数

整个程序使用了一下的函数

  1. SNUM expToNum(char exp[]);//将输入字符串转换为对应结构体
  2. void reverse(int a[],int len);//数组逆序
  3. int compareAbs(SNUM left,SNUM right);//比较两数绝对值大小
  4. SNUM anti_add(SNUM left,SNUM right);//元加法
  5. SNUM anti_sub(SNUM left,SNUM right);//元减法
  6. SNUM add(SNUM left,SNUM right); //加法
  7. SNUM sub(SNUM left,SNUM right); //减法
  8. SNUM multiply(SNUM left,SNUM right); //乘法
  9. SNUM divide(SNUM left,SNUM right); //除法
  10. SNUM mod(SNUM left,SNUM right);//求摸运算

函数的定义

  1. SNUM multiply(SNUM left,SNUM right){
  2. //left作为被乘数,right作为乘数
  3. SNUM mul = (struct num*)malloc(sizeof(struct num));
  4. int i,j;
  5. for(i=;i<LEN;i++){
  6. mul->number[i]=;
  7. }
  8.  
  9. if(left->symbol==right->symbol){
  10. mul->symbol='+';
  11. }else{
  12. mul->symbol='-';
  13. }
  14.  
  15. for(i=;i<right->len;i++){
  16. for(j=;j<left->len;j++){
  17. mul->number[i+j]+=left->number[j]*right->number[i];
  18. }
  19. }
  20.  
  21. // //进位化简
  22. int len = left->len+right->len-; //长度
  23.  
  24. //
  25. for(i=;i<len;i++){
  26. mul->number[i+]+=mul->number[i]/;
  27. mul->number[i]%=;
  28.  
  29. if(i==len-){
  30. if(mul->number[i+]!=){ //还存在高位
  31. len++;
  32. }else{ //进位完毕,退出
  33. break;
  34. }
  35. }
  36. }
  37.  
  38. // //舍去多余0位
  39. for(i=len-;i>=;i--){
  40. if(mul->number[i]==){
  41. len--;
  42. }else{
  43. break;
  44. }
  45. }
  46. if(len==){
  47. len=;
  48. }
  49.  
  50. mul->len=len;
  51.  
  52. free(left);
  53. free(right);
  54. return mul;
  55. }
  56.  
  57. //减一个数等于加上一个数的相反数
  58. SNUM sub(SNUM left,SNUM right){
  59. right->symbol=(right->symbol=='+'?'-':'+');
  60. return add(left,right);
  61. }
  62.  
  63. //比较两数绝对值大小
  64. int compareAbs(SNUM left,SNUM right){
  65. if(left->len>right->len){ //left的位数更多
  66. return ;
  67. }else if(left->len<right->len){ //right的位数更多
  68. return -;
  69. }else{
  70. int i=left->len-;
  71. while(i>=){ //从高位开始比较
  72. if(left->number[i]>right->number[i]){
  73. return ;
  74. }
  75. if(left->number[i]<right->number[i]){
  76. return -;
  77. }
  78. i--;
  79. }
  80. return ; //两者绝对值相等
  81. }
  82. }
  83.  
  84. SNUM expToNum(char exp[]){
  85.  
  86. SNUM temp=(struct num*)malloc(sizeof(struct num));
  87.  
  88. int locan=;
  89. //确定正负号
  90. if(exp[]=='+'||exp[]=='-'){
  91. temp->symbol=exp[];
  92. locan++;
  93. }else{
  94. temp->symbol='+';
  95. }
  96.  
  97. //输入到数组
  98. int count=;
  99. while(exp[locan]!='\0'){
  100. temp->number[count]=exp[locan]-'';
  101. locan++;
  102. count++;
  103. }
  104.  
  105. int i=count;
  106. for(i=count;i<LEN-;i++){
  107. temp->number[i]=;
  108. }
  109.  
  110. temp->len=count;
  111.  
  112. //数组逆序从个位开始计算
  113. reverse(temp->number,temp->len);
  114.  
  115. return temp;
  116. }
  117.  
  118. //数组逆序
  119. void reverse(int a[],int len){
  120. int i,temp;
  121. for(i=;i<len/;i++){
  122. temp = a[i];
  123. a[i] = a[len--i];
  124. a[len--i] = temp;
  125. }
  126. }
  127.  
  128. //元加法,假设left和right都为正数或0
  129. SNUM anti_add(SNUM left,SNUM right){
  130. int i=;
  131.  
  132. while(i<left->len||i<right->len){
  133. int sum=;
  134. sum=left->number[i]+right->number[i];
  135. if(sum>=){
  136. left->number[i]=sum%;
  137. left->number[i+]+=sum/; //进位
  138. }else{
  139. left->number[i]=sum; //不进位
  140. }
  141.  
  142. i++;
  143. }
  144.  
  145. if(left->number[i]!=){
  146. i+=;
  147. }
  148.  
  149. left->len=i;
  150. return left;
  151. }
  152.  
  153. //实现正数或负数的加法
  154. SNUM add(SNUM left,SNUM right){
  155. SNUM temp;
  156. if(left->symbol==right->symbol){
  157. temp = anti_add(left,right);
  158. }else{
  159. if(compareAbs(left,right)>=){
  160. temp = anti_sub(left,right);
  161.  
  162. }else{
  163. temp = anti_sub(right,left);
  164. }
  165. }
  166. return temp;
  167. }
  168.  
  169. //元减法,假设left>=right,left和right均为正数或0
  170. SNUM anti_sub(SNUM left,SNUM right){
  171. int i=;
  172. int count=;
  173. while(i<left->len){
  174. int temp = left->number[i]-right->number[i];
  175. if(temp<){
  176. left->number[i+]-=;
  177. left->number[i]=temp+; //退位
  178. }else{
  179. left->number[i]=temp;
  180. }
  181.  
  182. count+=;
  183.  
  184. i++;
  185. }
  186.  
  187. //舍掉多余的0
  188. for(i=count-;i>=;i--){
  189. if(left->number[i]==){
  190. count--;
  191. }else{
  192. break;
  193. }
  194. }
  195.  
  196. if(count==){
  197. count++;
  198. }
  199.  
  200. left->len=count;
  201. return left;
  202.  
  203. }

C语言实现大数四则运算的更多相关文章

  1. 大数四则运算之加法运算--------C语言版(未考虑负数)

    /* 声明两个字符数组,用于存储大数,声明两个整数型数组便于计算,将字符数组中的元素转换为对应整数存于整数数组中,将低位放在整数数组低位,便于对齐计算 判断是否有进位,计算结果高位先输出,从数组后往前 ...

  2. 大数四则运算之减法运算-----c语言版

    /* 分三种情况: 1.减数长度大于被减数 交换减数与被减数,输出负号,方便减 2.减数长度等于被减数(分三种情况) a.减数大于被减数,类似1情况1 b.减数等于被减数,两数相等,直接输出0,完成. ...

  3. 大数四则运算java(转)

    // 大数的四则运算 #include <iostream> #include <string> #include <algorithm> using namesp ...

  4. C语言#自动生成四则运算的编程

    #include <iostream> #include <stdio.h> #include <stdlib.h> #include <time.h> ...

  5. C语言求大数的阶乘

    我们都知道如何计算一个数的阶乘,可是,如果这个数很大呢,该如何计算? 当一个数很大时,利用平常的方法是求不出来它的阶乘的,因为数据超出了范围.因此我们要用数组来求一个大数的阶乘,用数组的每位表示结果的 ...

  6. C语言:大数取余

    大数取余数(数组) 今天做学校的oj时遇到一题,问题可见一下截图: 查遍各大论坛,都没有遇到合适的方法,普通方法不可用,要采用数组的形式. 被除数超过long long类型,不能采用常规思路,否则会出 ...

  7. C语言:大数求和

    点击获取题目 1410: [蓝桥杯]高精度加法 时间限制: 1 Sec  内存限制: 256 MB提交: 28  解决: 20[状态] [提交] [命题人:外部导入] 题目描述 输入两个整数a和b,输 ...

  8. java实现超大整数加减乘除四则运算

    原理: 用数组存储数字,按照计算法则进行运算. 代码: package com.hdwang; import java.util.regex.Matcher; import java.util.reg ...

  9. C 语言学习的第 05 课:C 语言基础(01)

    C语言程序中的绝大部分应该记录在以.c作为扩展名的文件里,这种文件叫做C语言    程序的源文件. C语言中还包括以.h作为扩展名的文件,这种文件叫做头文件. C语言中的四则运算: 加:+ 减:- 乘 ...

随机推荐

  1. [UE4]添加射击的准心

    其实就是创建一个UI Widget,在UI Widget中添加一个准心图片(png)格式,准心图片设置为屏幕居中对齐,然后在自定义的GameMode中把这个UI Widget添加到视图中.

  2. 用 tornado 做网站 (7)

    转自:http://wiki.jikexueyuan.com/project/start-learning-python/309.html 用 tornado 做网站 (7) 到上一节结束,其实读者已 ...

  3. javascript事件处理程序的3个阶段

    第一阶段:HTML事件处理阶段.就是在元素里面添加onclick之类的属性来调用某个函数. <input type="button" value="单击" ...

  4. 6.12-PrepareStatement,JdbcUtil 读取数据库配置文件properties,dao模式

    一.PrepareStatement 防止sql注入 PrepareStatement 是预编译sql语句 更加灵活,更有效率 executeUpdate() 做增删改 executeQuery() ...

  5. MySQL ALTER讲解

    当我们需要修改数据表名或者修改数据表字段时,就需要使用到MySQL ALTER命令. 开始本章教程前让我们先创建一张表,表名为:testalter_tbl. root@host# mysql -u r ...

  6. python函数入门

    知识内容: 1.函数的作用 2.函数的定义与调用 3.函数的返回值 4.函数的参数 5.局部变量与全局变量 6.作用域 一.函数的作用 1.复用代码 将可能重复执行的代码封装成函数,并在需要执行的地方 ...

  7. 《图像处理实例》 之 目标旋转矫正(基于区域提取、DFT变换)

    目标:1.把矩形旋转正.          2.把文字旋转校正.                                                                     ...

  8. smyfony2-curd-数据库创建

    1创建类

  9. 配置WDS支持使用UEFI模式启动

    使用WDS通过Legacy+MBR方式部署操作系统不难,网上文章也有很多,本文就不赘述了,主要记录一下通过UEFI+GPT方式部署. 网上文章虽然也有介绍通过UEFI+GPT方式部署,但大多数说的比较 ...

  10. 微信小程序注册身份证验证

    // 校验身份证号 //校验码校验 checkCode: function (val) { var p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2])) ...