八进制大数运算

来源:互联网 发布:unity3d哪个公司好 编辑:程序博客网 时间:2024/06/06 00:53

      参加学校某实验的机试,有个题目是20到40位的八进制大数运算。当时只写出了加减,回来之后按照当时的思路扩充了乘除。

       定义大数结构

      

typedef struct num{char attribute;int lenth;int oct[N1];}NUM;


      1. 加法是按位运算,结果%8,大于7则保存进位,进位为(结果/8)。

NUM* plus(NUM *a,NUM *b){NUM *carry;NUM *result;int i,j,k;int len_a,len_b;int mid;result = init(result);carry = init(carry);len_a = a->lenth;len_b = b->lenth;i = N1-1;j = N1-1;k = N1-1;while(i>=N1-len_a||j>=N1-len_b){mid = a->oct[i] + b->oct[j] + carry->oct[k];if(mid>7)result->oct[k] = mid % 8;else result->oct[k] = mid;carry->oct[k-1] = mid/8;i--;j--;k--;}if(carry->oct[k]!=0){result->oct[k] = carry->oct[k];result->lenth = N1 - k;}else result->lenth = N1 - k - 1;return result;}
      2. 减法与加法想法类似,小减大的情况,直接取负,没有按位处理。所以有一个判断大小的函数。

      判断大小:

/*1 a>b 2 a<b 3 a==b*/int judge(NUM* a,NUM* b){int i;if(a->lenth > b->lenth)return 1;if(a->lenth < b->lenth)return 2;else{i = N1 - a->lenth;while(i<N1){if(a->oct[i]>b->oct[i])return 1;if(a->oct[i]==b->oct[i])i++;else return 2;}return 3;}}

      减法:

NUM* minus_decision(NUM *a,NUM *b){int x;NUM* result;x = judge(a,b);if(x == 1){result = minus(b,a);result->attribute = '-';return result;}else return (minus(a,b));}

NUM* minus(NUM *a,NUM *b){NUM *carry;NUM *result;int i,j,k;int len_a,len_b;int mid;result = init(result);carry = init(carry);len_a = a->lenth;len_b = b->lenth;i = N1-1;j = N1-1;k = N1-1;while(i>=N1-len_a){if((a->oct[i] - carry->oct[k])<b->oct[j]){mid = a->oct[i] + 8 - b->oct[j] - carry->oct[k];carry->oct[k-1] = 1;}else mid = a->oct[i] - b->oct[j] - carry->oct[k];result->oct[i] = mid;i--;j--;k--;}i++;result->lenth = N1 - i;while(i<N1-1){if(result->oct[i]==0){result->lenth--;i++;}else break;}return result;}

      3. 乘法。按位调用加法函数,然后移位累加。

NUM* times(NUM *a,NUM *b){NUM* result1;NUM* result2;int i,j;int len_b;int repeat;int move;result1 = init(result1);result2 = init(result2);result1->lenth = a->lenth;result2->lenth = b->lenth;if(judge(a,result1) == 3 ||judge(b,result2) == 3)return result2;len_b = b->lenth;i = N1 -1;while(i>= N1 - len_b){move = N1-1-i;repeat = b->oct[i];result1 = a;while(repeat>1){result1 = plus(result1,a);repeat--;}j = N1 - result1->lenth;while(j<N1){result1->oct[j-move] = result1->oct[j];j++;}j -=move;while(j<N1){result1->oct[j] = 0;j++;}result1->lenth += move;result2 = plus(result1,result2);i--;}return result2;}

      4. 除法。除法处理起来比较复杂。这里只处理整除。假设: 423/23,先算42/23,再循环求商,结果调用减法函数求余数,再重复上面步骤知道余数比23小。

NUM* divide(NUM *a,NUM *b){NUM* result;NUM* mid;NUM* tmp;int re[N1];int len_re;int len_a,len_b;int i,j,k,x,p;result = init(result);mid = init(mid);tmp = init(tmp);x = 0;if(judge(a,b)==1){len_a = a->lenth;len_b = b->lenth;i = N1 - len_a;j = N1 -1;while(j>=N1-len_b){mid->oct[j] = a->oct[i+len_b-1];i--;j--;}i = N1 - len_a + len_b -1;mid->lenth = len_b;while(i<N1){if(judge(mid,b)!=2){re[x] =1;tmp->oct[N1-1] = re[x];tmp->lenth = 1;while(judge(times(b,tmp),mid) != 1){re[x]++;tmp->oct[N1-1] = re[x];}re[x]--;tmp->oct[N1-1] = re[x];mid = minus(mid,times(b,tmp));if(mid->lenth == 1&&mid->oct[N1-1]==0)mid->lenth = 0;}else{    re[x] = 0;}p = N1 - mid->lenth;while(p<N1){mid->oct[p-1] = mid->oct[p];p++;}i++;mid->oct[N1-1] = a->oct[i];mid->lenth++;k = mid->lenth;while(k>=1){    if(mid->oct[N1-k]==0)    {mid->lenth--;k--;}    else break;}x++;}        len_re = x;}if(judge(a,b)==2){re[0] =0;len_re =1;}if(judge(a,b)==3){re[0] =1;len_re =1;}for(i=N1-1,j=0;j<len_re;j++,i--){result->oct[i] = re[j];}result->lenth = len_re;return result;}

只是初略写一下。代码写得很垃圾,仅供参考。没有八进制数检测,位数和结果溢出等等控制。





原创粉丝点击