大整数运算---模拟笔算
来源:互联网 发布:mac上的抠图软件 编辑:程序博客网 时间:2024/04/28 10:50
/**m=a[k]×10k-1+a[k-1]×10k-2+….+a[2]×10+a[1]*其中a[0]保存该长整数的位数。**模拟笔算*/#include<iostream>#include<cstring>using namespace std;#define SIZE 255void getl(char* n);//获取长整数void prt(char* n);//打印长整数int cmp(char* n1, char* n2);//比较长整数大小void swap(char * n);//长整数位交换void cpy(char* n1, char* n2);//复制长整数/**********************************************///乘法void mul(char* n1, char* n2);void muld(char* n, int t, char num);//位乘/**********************************************///除法void div(char* n1, char* n2, char* q);/**********************************************///加法void plu(char* n1, char* n2);int plua(char* n, int off, char num);//位加/**********************************************///减法int sub(char* n1, char* n2);//返回0正1负int suba(char* n1, int off, char num);//位减/**********************************************/int main(int argc, char** argv){cout<<"长整数乘除法运算。"<<endl<<endl;while(1){cout<<"请选择运算: 1.乘法; 2.除法。"<<endl;int t;//t=2;cin>>t;if(t == 1){cout<<"请依次输入 被乘数、乘数。"<<endl;}else if(t == 2){cout<<"请依次输入 被除数、除数。"<<endl;}else{cout<<"输入错误,请重试。";continue;}fflush(stdin);char n1[SIZE]={0},n2[SIZE]={0};getl(n1);getl(n2);if(t == 1){mul(n1, n2);cout<<"结果:";prt(n1);}else{ char q[SIZE] = {0};if(n2[0]==1 && n2[1]==0){cout<<"输入错误:除数不能为0"<<endl;continue;} div(n1, n2, q); cout<<"商:";prt(n1);cout<<"余数:"; prt(q);}}return 0;}/**********************************************/void getl(char* n){//从console获取一个长整数char tmp;while(tmp = getchar()){if(tmp <= '9'&&tmp >= '0'){break;}}int i=1;while(tmp <= '9'&&tmp >= '0'){n[i] = tmp;n[i] -= '0';tmp = getchar();i++;}n[0] = i-1;swap(n);}void prt(char* n){ //打印一个大整数if(n[0] == 0){cout<<"0";} for(int i=n[0];i >= 1; i--){ cout<<char(n[i] + '0'); } cout<<endl;}int cmp(char* n1, char* n2){ //比较两个大整数的大小 n1>n2返回1 if(n1[0] > n2[0]){ return 1; }else if(n1[0] < n2[0]){ return -1; }else{ for(int i=n1[0]; i>=1; i--){ if(n1[i] == n2[i]){ continue; }else{ if(n1[i] > n2[i]){ return 1; }else{ return -1; } } } } return 0;}void swap(char* n){//按脚码逆置一个大整数char tmp;for(int i=1; i<=n[0]/2; i++){tmp = n[i];n[i] = n[n[0] - i + 1];n[n[0] - i + 1] = tmp;}}void cpy(char* n1, char* n2){//将n1复制为n2for(int i=0; i<=n2[0]; i++){n1[i] = n2[i];}}/**********************************************/void mul(char* n1, char* n2){//乘法,结果保存在n1char result[SIZE] = {0};char tmp[SIZE] = {0};for(int i=1; i<=n2[0]; i++){cpy(tmp, n1);muld(tmp, i - 1, n2[i]);plu(result, tmp);}cpy(n1, result);}void muld(char* n, int t, char num){//个位数乘,将n乘以 后跟t个零的个位数num,完成进位char k = 0;//进位数int i;for(i = 1; i<=n[0]; i++){n[i] *= num;n[i] += k;if(n[i] > 9){k = n[i]/10;n[i] %= 10;}else{k = 0;}}if(k){n[0]++;n[i] = k;}//左移for(int i=n[0]; i>=1; i--){n[i+t] = n[i];}for(int i=1; i<=t; i++){n[i] = 0;}n[0] += t;}/**已废弃int mula(char* n, int off, char num){//位乘,将n偏移为off的地方乘上num,返回进位n[off] *= num;cout<<"off "<<off<<endl;logi("n[off] ",n[off]%10);logi("num ",num);if(n[off] > 9){n[off] %= 10;return n[off]/10;}else{return 0;}}void mulplu(char* n, int off, char num){//乘法中用到的加法,将n偏移为off的位加上num,完成进位,结果保存在nint i;char k = n[off];for(i=off; k||i==off; i++){k = plua(n, i, k);}//i:最前面的不是进位的偏移if(i-2 > n[0]){n[0] = i-2;}}*//**********************************************//*从n1最高位开始余数=0while(可以向右截取){ 余数 加上向右取的 while(取得的数小于n2){ 向右取 } while(余数 >= n2){ 商++ 余数 -= n2 }商放在结果的 截取位的最右位余数乘以10}*/void div(char* n1, char* n2, char* q){//除法,商保存在n1,余数保存在qchar remd[SIZE] = {0};//余数 char ans[SIZE] = {0};//结果 char d[SIZE] = {0};//截取的一位数d[0] = 1;char ten[SIZE] = {0};//长整数10ten[0] = 2;ten[1] = 0;ten[2] = 1;//保存未乘10的个位余数char tn[SIZE] = {0};bool over = false; int w = n1[0];//截取位while(w != 0){d[1] = n1[w];plu(remd, d);while(cmp(remd, n2) == -1){//乘10之前保存个位余数if(w == 1){cpy(tn, remd);}mul(remd, ten);w--;//向右取之前确定可以取if(w == 0){over = true;break;}d[1] = n1[w];plu(remd, d);}if(over){break;}char qu = 0;//商while(cmp(remd, n2) != -1){qu++;sub(remd, n2);}//加在结果的当前截取到位plua(ans, w, qu);//乘10之前保存个位余数if(w == 1){cpy(tn, remd);}mul(remd, ten);w--;}cpy(remd, tn);//计算ans的位数 for(int i=n1[0]; i>=1; i--){ if(ans[i] != 0){ ans[0] = i; break; } } cpy(n1, ans); cpy(q, remd);}/**********************************************/void plu(char* n1, char* n2){//加法,结果保存在n1int i;int k = 0;int maxlen = n1[0]>n2[0]?n1[0]:n2[0];for(i=1; i<=maxlen; i++){k = plua(n1, i, n2[i] + k);}n1[0] = maxlen;if(k){n1[0]++;n1[i] = k;}}int plua(char* n, int off, char num){//位加法,将n偏移为off的地方加上num,返回进位n[off] += num;if(n[off] > 9){int t = n[off]/10;n[off] %= 10;return t;}else{return 0;}}/**********************************************/int sub(char* n1, char* n2){ //减法,n1:被减数 n2:减数 n1>=n2 结果放在n1 返回1负数0正数 int foo; char t[SIZE] = {0}; if((foo = cmp(n1, n2)) == -1){ cpy(t, n2); cpy(n2, n1); cpy(n1, t); } char w = 0;//借位数 int i=1; for(;i<=n2[0]; i++){ w = suba(n1, i, n2[i] + w); } while(w){ w = suba(n1, i, n2[i] + w); i++; } //清除无效0 for(int k=n1[0]; k>=1; k--){ if(n1[k] == 0){ n1[0]--; }else{ break; } } if(foo == -1){ //复原n2 cpy(n2, t); return 1; }else{ return 0; }}int suba(char* n, int off, char num){//位减法,将n偏移为off的地方减去num,返回借位 n[off] -= num; if(n[off] < 0){ n[off] += 10; return 1; }else{ return 0; }}/**********************************************/
0 0
- 大整数运算---模拟笔算
- 11.用链表模拟大整数加法运算
- 用链表模拟大整数加法运算
- 大整数运算
- 大整数运算类
- 大整数运算问题
- C++ 大整数运算
- 浅析大整数运算
- 大整数运算包
- 大整数运算
- Java 大整数运算
- C++大整数运算
- 大整数运算java
- 大整数运算
- 大整数运算
- 大整数型运算
- 正常大整数运算
- 大整数模拟
- spring mvc 验证码功能
- js 正则表达式 验证身份证号码
- JS在子类中用Object.getPrototypeOf去调用父类方法
- VS2008创建dll,并使用dll
- TCP/IP入门(3) --传输层
- 大整数运算---模拟笔算
- 大巧不工Web前端设计修炼之道——(3)从过去到未来,前端设计演变之路
- 教你用ADO+VC在程序中完成创建和修改ACCESS数据库
- ERP系统对部门经理的好处
- js 正则表达式 验证手机号码
- Html5 Canvas画线有毛边解决方法
- safiri webkit 开发 on linux (ubuntu or fedora)
- ATL TRACE
- SQL中Group By的使用