Windroid的水房

/**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返回1if(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++;}//清除无效0for(int k=n1[0]; k>=1; k–){if(n1[k] == 0){n1[0]–;}else{break;}}if(foo == -1){//复原n2cpy(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;}}/**********************************************/

不要气馁于那前方的阴影,那只是因为我背后光芒万丈

Windroid的水房

相关文章:

你感兴趣的文章:

标签云: