大数的运算
来源:互联网 发布:金扎软件 编辑:程序博客网 时间:2024/05/22 15:25
大数运算指的是对C语言中那些大到超出表示范围的数的运算,比如9999999999999999999999999999999+9999999999999999999999999。C语言中无法将这么大的一个数存储到变量中,这里就要用到大数的运算了。
大数加法:
思路很简单,就是把这个“大数”以字符串的形式存入数组中,然后倒序放入整型数组便于逐步相加。附上代码如下
void add(char*num1, char*num2){ int intnum1[MAX] = { 0 }; int intnum2[MAX] = { 0 }; int i = 0, j = 0; int len1 = strlen(num1); int len2 = strlen(num2); int len = len1 > len2 ? len1 : len2; for (i = len1 - 1; i >= 0; i--)//将数字逆序存入整型数组中,便于相加 { intnum1[j++] = num1[i]-48; } j = 0; i = 0; for (i = len2 - 1; i >= 0; i--) { intnum2[j++] = num2[i]-48; } for (i = 0; i < len+1; i++)//逐步相加 { intnum1[i] += intnum2[i]; if (intnum1[i]>9) { intnum1[i] -= 10; intnum1[i + 1]++;//有进位,下一位加1 } } for (i = len; i >= 0; i--) { if (i == len&&intnum1[i] == 0) ; else printf("%d", intnum1[i]); }}
大数减法:
减法的思路和加法类似。也是将俩数存入到字符数组中,然后倒序放入整型数组便于逐步相减。但区别于加法的一点是减法需要事先判断好那个数字比较大,由较大数减去较小数。最后输出的时候要注意正负号,代码如下:
void sub(char*num1, char*num2){ int intnum1[MAX] = { 0 }; int intnum2[MAX] = { 0 }; int i = 0, j = 0; int len1 = strlen(num1); int len2 = strlen(num2); int len = len1 > len2 ? len1 : len2; /*判断哪个数比较大*/ char*biggersize = judgesize(num1, num2); for (i = len1 - 1; i >= 0; i--)//倒序存入整型数组中 { intnum1[j++] = num1[i] - 48; } j = 0; i = 0; for (i = len2 - 1; i >= 0; i--) { intnum2[j++] = num2[i] - 48; } if (biggersize==num1) for (i = 0; i < len; i++)//逐步相减 { intnum1[i] -= intnum2[i]; if (intnum1[i] < 0) { intnum1[i] += 10; intnum1[i + 1]--; } } else for (i = 0; i < len; i++) { intnum2[i] -= intnum1[i]; if (intnum2[i]<0) { intnum2[i] += 10; intnum2[i + 1]--; } } if (biggersize==num1) { for (i = len-1; i >= 0; i--) { if (i == len-1&&intnum1[i] == 0) ; else printf("%d", intnum1[i]); } } else { printf("-"); for (i = len-1; i >= 0; i--) { if (i == len-1&&intnum2[i] == 0) ; else printf("%d", intnum2[i]); } }}
大数的乘法:
相对于前两者,乘法稍微复杂一些。乘法的实现主要基于加法:把一个乘数每位上的数取下来分别与另一个数相乘(这里要注意相乘的结果的大小,比如把十位上的数取下来与另一乘数进行运算,要记得在后面补上一个0),然后把相乘的结果加起来就是结果。
代码如下:
void mul(char*num1, char*num2){ int intnum1[MAX] = { 0 }; int intnum2[MAX] = { 0 }; int pt[MAX] = { 0 }; int num[MAX] = { 0 }; int i = 0, j = 0, k = 0, t = 0; int tenpos = 0;//俩个位数相乘的值得十位上的数 int len1 = strlen(num1); int len2 = strlen(num2); for (i = len1 - 1; i >= 0; i--) { intnum1[j++] = num1[i] - 48; } j = 0; i = 0; for (i = len2 - 1; i >= 0; i--) { intnum2[j++] = num2[i] - 48; } for (i = 0; i < len2; i++)//取intnum2上的每位来相乘 { /*intnum2上的每位与intnum1上存的数相乘*/ for (j = 0; j < len1+1; j++) { /*t的作用是确保每一步相乘后,末尾0的个数*/ pt[j+t] = intnum2[i] * intnum1[j]+tenpos; tenpos = 0; if (pt[j+t]>9)//记录进位 { tenpos = pt[j+t] / 10; pt[j+t] %= 10; } } /*相乘的结果进行加法运算(大数加法)*/ for (k = 0; k < len1+t+1; k++) { num[k] += pt[k]; if (num[k]>9) { num[k] -= 10; num[k + 1]++; } } t++; memset(pt, 0, sizeof(int)*len1); } for (i = MAX - 1; i >= 0;i--)//寻找相乘结果的第一位数 if (num[i] != 0) { j = i; break; } for (i = j; i >= 0;i--) printf("%d", num[i]);}
大数除法:
思路很简单,但是实现起来很复杂。这里通过例子来说明:
假设a={2 4 2 3 1},b={2 3},结果result={0 0 0 0 0}:
先取a[0]a[1]即24,减去b一次,得a={0 1 2 3 1},result={0 1 0 0 0};
再取a[1]a[2]即12,发现它小于b,则多取一位,取a[1]a[2]a[3]即123,减b五次,得a={0 0 0 8 1},result={0 1 0 5 0};
再取a[3]a[4]即81,减b三次,得a={0 0 0 1 2},result={0 1 0 5 3}。
/*比较除数与被除数上相应位的大小*/int judgedivisorsize(int*num1, int*num2,int lendivisor,int t){ int i = 0; if (t == 1) return 1; for (i = 0; i < lendivisor; i++) { if (num1[i]>num2[i])//被除数大于除数返回1 return 1; else if (num1[i] < num2[i])//小于返回-1 return -1; else ; } return 1;//相等的时候返回1}void div(char*num1, char*num2){ int intnum1[MAX] = { 0 }; int intnum2[MAX] = { 0 }; char result[MAX] = { 0 };//记录商的数组 int i = 0, j = 0, k = 0, t = 0; int len1 = strlen(num1); int len2 = strlen(num2); int lenresult = 0; if (num2 == judgesize(num1, num2)) { printf("结果=0\n"); printf("余数=%s", num2); return; } for (i = 0; i < len1 ; i++) { intnum1[i] = num1[i] - 48; } for (i = 0; i < len2; i++) { intnum2[i] = num2[i] - 48; } for (i = 0; i <= len1 - len2; i++) { if (judgedivisorsize(intnum1 + i, intnum2, len2, t) >= 0) { /*t的作用:使上一轮比较的数的首位留到下一轮比较(如果首位不为0的话)。*/ while (judgedivisorsize(intnum1 + i, intnum2, len2, t) >= 0) { for (j = len2 - 1; j >= 0; j--) { intnum1[j + i] -= intnum2[j]; if (intnum1[j + i] < 0) { intnum1[j + i] += 10; intnum1[j + i - 1]--; } /*当上一轮的首位为0的时候要即使调整,便于正确判断本轮比较的数的大小*/ if (intnum1[i - 1] == 0) t = 0; } result[len2 + i - 1]++; } /*当一轮比较结束,例如24563/13,24减去13余下11,不够减,intnum1首位的1要留到下一轮去比较,设置t为1*/ /*当intnum1首位为0的时候,并不需要留到下一轮*/ for (k = i; k < len2 + i; k++) { if (intnum1[i] == 0) break; t = 1; } } else { /*11234/12,11小于12,不够减,设置t为1,使得下一次112与12比较。*/ if (intnum1[i] != 0) t = 1; if (result[len2 + i - 1] == '\0') result[len2 + i - 1] = '0'; } } printf("商="); lenresult = result[len1 - 1] == 0 ? len1 - 1 : len1; for (i = 0; i < lenresult; i++) { if (result[i] != '0') result[i] += '0'; } printf("%s\n余数=", result); j = 0; for (i = len1 - len2; i < len1; i++) { if (intnum1[i] != 0) { j = i; break; } } for (i = j; i < len1; i++) printf("%d", intnum1[i]); printf("\n");}
0 0
- 大数运算的算法
- 大数的运算
- 大数间的运算
- 大数的加减运算
- 大数的运算思想
- 大数的运算
- 项目:大数的运算
- 精简的大数运算
- 高精度大数运算的实现
- 大数的取余运算
- 需要大数运算的程序
- 大数的加减乘除运算(C++)
- 有关大数的运算(1)
- 有关大数的运算(2)
- 【C++】C++大数的运算
- 十进制大数的加法运算
- 大数运算
- 大数运算
- 写论文必看要点
- 冒泡的优化
- 基于FS4412嵌入式系统移植(5) 内核移植
- SDUT1130数据结构上机测试1:顺序表的应用
- redis学习之Jedis使用线程池封装redis的基本操作及spring的简单封装
- 大数的运算
- 263. Ugly Number
- redis 编译报错 CC:not find 和 error: jemalloc/jemalloc.h: No such file or directory
- c文件操作 (转)
- 为什么苹果的利润不会受HTML5影响?
- Android day4:Java的类型转换、Scanner、错误类型
- AIX 6.1 11g RAC数据库怎样改网段
- 动态规划 ——总结.
- Learning Handler