📄 arrayclass.cpp
字号:
#include "stdafx.h"
#include "BignumClass.h"
#include <iostream.h>
ArrayClass::ArrayClass( int *array)//构造函数
{
for(int i=0;i<MAX;i++)
arr[i]=array[i];
}
ArrayClass::ArrayClass()
{
for(int i=0;i<MAX;i++) arr[i]=0;
}
ArrayClass ArrayClass::operator = ( ArrayClass &arr1)
{
for(int i=0;i<MAX;i++)
arr[i]=arr1.arr [i];
return *this;
}
ArrayClass operator + ( ArrayClass &arr1, ArrayClass &arr2 ) //数组相加
{
ArrayClass arr3;//临时数组
BignumClass str;
for(int i=1;i<MAX-1;i++)
arr3.arr [i] = arr1.arr [i]+arr2.arr [i];
str.redressal (arr3.arr);
return arr3;
}
////这个减法最好是用在大数减小数的时候,或只有a-b的最后情况,对a-b-c-d+e+f=a+e+f-(b+c+d)来求
ArrayClass operator - (ArrayClass &arr1, ArrayClass &arr2 )//数组相减
{//大数减小数
ArrayClass tmp;
BignumClass str;
int tag = 1; //arr1>arr2 时为1
for(int t=1 ; t < MAX-1 ; t++)
{
if(arr1.arr [t] < arr2.arr [t])
{
tag=0;tmp=arr1;arr1=arr2;arr2=tmp;break;
}
if(arr1.arr [t] > arr2.arr [t])break;
}
for(t=MAX*2/3+str.minimal(arr1.arr[MAX-1],arr2.arr[MAX-1]);t>MAX*2/3-str.maximal(arr1.arr[0],arr2.arr[0]);t--)
{
if(arr1.arr [t] < arr2.arr [t])// 要借位
{
arr1.arr [t-1] = arr1.arr [t-1]-1;
arr1.arr [t] = 10 + arr1.arr [t];
}
arr1.arr[t]=arr1.arr[t]-arr2.arr[t];
}
str.getDigit(arr1.arr);
if( tag==0)arr1.arr [MAX*2/3-arr1.arr[0]+1]=arr1.arr [MAX*2/3-arr1.arr [0]+1]*(-1);
return arr1;
}
ArrayClass operator * ( ArrayClass &arr1, ArrayClass &arr2 )//数组相乘
{
ArrayClass arr3;//临时数组// 123.323 X 22.3 = //0.0000000001*0.000000002?/
ArrayClass arrtemp;
arr1.arr [MAX-1]>arr2.arr [MAX-1]?arr3.decimalDispose(arr1.arr,arr2.arr):arr3.decimalDispose(arr2.arr,arr1.arr);//保证第一个参数的小数位大于第二个参数
BignumClass s ;
int end_arr3=MAX*2/3+arr1.arr [MAX-1]+arr2.arr [MAX-1]; //这是arr3.arr[]r的最后一位小数的位置
int k;
if(arr1.arr [0]+arr2.arr [0]>MAX*2/3) return arr3 ;//整数位超出了范围
else
{
for(int t=MAX*2/3+arr2.arr [MAX-1];t>MAX*2/3-arr2.arr[0];t--)//22.3
{
s.arrayToZero (arrtemp.arr);// ::arrayToZero(int narr[])
k = end_arr3;
for(int j=MAX*2/3+arr1.arr [MAX-1];j>MAX*2/3-arr1.arr [0];j--)//123.323
{
arrtemp.arr[k--]=arr2.arr [t]*arr1.arr [j];
}
s.getDigit (arrtemp.arr);
arr3=arr3+arrtemp;
end_arr3--;
}
}
return arr3;
}
ArrayClass operator / ( ArrayClass &arrfir, ArrayClass &arrsce)//数组相除// arr1/arr2
{
ArrayClass arr1;
ArrayClass arr2;
BignumClass s1;
arr1=arrfir; arr2=arrsce;
arr1.move(arr1.arr ,arr2.arr );//移位
int nhead_divisor= arr2.arr [MAX*2/3 - arr2.arr [0] + 1];//除数的首位
int nhead_dividend ;//被除数的首位
int nquotient;//商
int arrquotient[MAX];
s1.arrayToZero(arrquotient );//数组初值都为0
for(int i=MAX*2/3 - arr1.arr[0] + 1/*被除数的首位下标*/;i<=MAX - 2 - arr2.arr [0]/*???*/;)
{
for(;arr1.arr[i]==0&&i<=MAX - 2 - arr2.arr[0]+1;i++);//如到了0003232就要作舍去0
s1.arrayToZero(arr1.tmparr );//数组初值都为0
nhead_dividend= arr1.arr[i];
nquotient=nhead_dividend/nhead_divisor; //第一次求商
if(nquotient==0) nhead_dividend=10*nhead_dividend + arr1.arr[++i];
nquotient=nhead_dividend/nhead_divisor; //第二次求商
do{
if(nquotient==0){i=i+1;nquotient=9;}//1010011/101 不会出现要我商0的情况
//只有14222/19= 当i 在1时1/1==1但14<19;商这时就减为0了解不下去了,只有i加一位,商9再说
s1.arrayToZero(arr1.tmparr );//数组初值都为0
arr1.numMul(nquotient,arr2.arr ,i);
nquotient--;
}while(arr1.compare(arr1.arr,arr1.tmparr)==0);
nquotient=nquotient+1; //最终求商 //三次都是一位一位的求商
arrquotient[i+arr2.arr [0] - 1]=nquotient;//每得一位商就存好
arr1.numSub(arr1.arr,arr1.tmparr,i-1,arr2.arr [0]);//把561003/123 (商4得492)变为69003 = (561003-492000)
if(s1.zero(arr1.arr)==1)break;//除尽了
}
s1.getDigit(arrquotient);//让商得到它的整数的整数和小数位数
s1.copy (arr1.arr ,arrquotient);
return arr1;
}
int operator % ( ArrayClass &arr1, ArrayClass &arr2 ) //数组是否有整除关系
{
//return 1 就是说不能除尽,为0 就是可以整除
ArrayClass arr3;
if(arr1.arr[MAX*2/3]!=0&&arr2.arr [MAX*2/3]==0)//65/10 1000000001/1000000000=1.000000 001
return 1;
if(arr1.arr[MAX*2/3]==5&&arr2.arr [MAX*2/3]!=5) //65/3 ?? 65/5
return 1;
//if(arr1.arr[MAX*2/3]%2==0&&arr2.arr [MAX*2/3]%2!=0)//62/5 ?? 62/4
// return 1; //646/323==2
if(arr1.arr[MAX*2/3]%2!=0&&arr2.arr [MAX*2/3]%2==0)//63/2 ?? 63/3
return 1;
//其它情况
arr3=arr1/arr2;
if(arr3.arr[MAX-1]==0) return 0;
else
return 1;
}
void ArrayClass::decimalDispose(int arrlong[],int arrshort[])//由于乘法时小数位过多不行就合理的舍弃几位
{
int all_length = MAX-2-MAX*2/3;
int nlong = arrlong[MAX-1];
int nshort = arrshort[MAX-1];
if(nlong+nshort<=all_length) return;//没有必要去小数位
if(nshort<=all_length/2)//只要去掉长的小数位
{
for(int t=all_length-nshort+MAX*2/3+1;t<MAX-1;t++) arrlong[t]=0;
arrlong[MAX-1] = all_length-nshort;
}
else //两者都要去
{
for(int t=all_length/2+1;t<MAX-1;t++) arrlong[t]=arrshort[t]=0;
arrlong[MAX-1]=arrshort[MAX-1] = all_length/2;
}
}
void ArrayClass::move(int arrdividend[],int arrdivisor[])//根据除数移位45/3
{
int a=MAX*2/3-arrdivisor[0];//除数可移位置;
int b=MAX*2/3-arrdividend[0];//被除数可移位置;
if(b<a) a=b;//保证a是最小的可移位置
int c=arrdivisor[MAX-1];//c是要移的位数
if(a<c) c=a;// 保证c是最终最小的要移位置
if(c==0)return;
arrdivisor[0]=arrdivisor[0]+c;
arrdividend[0]=arrdividend[0]+c;
for(int i=MAX*2/3-arrdivisor[0]+1;i<=MAX*2/3;i++)
arrdivisor[i]=arrdivisor[i+c];
for(;i<MAX;i++)//除数没有了小数
arrdivisor[i]=0;
for(i=MAX*2/3-arrdividend[0]+1;i<=MAX*2/3+arrdividend[MAX-1]-c;i++)//被除数的要移位
arrdividend[i]=arrdividend[i+c];
for(;i<MAX-2;i++)//
arrdividend[i]=0;
arrdividend[MAX-1]-c>0 ? arrdividend[MAX-1]=arrdividend[MAX-1]-c:arrdividend[MAX-1]=0;//不够移就说明没了小数
}
void ArrayClass::numMul(int nquotient ,int arrdivisor[],int nhead_dividend)//商乘以除数
{
BignumClass s1;
int k=MAX*2/3;
for(int t=nhead_dividend+arrdivisor[0]-1;t>=1&&k>=MAX*2/3-arrdivisor[0]+1;t--,k--)
{
tmparr[t]=nquotient*arrdivisor[k];
}
s1.redressal(tmparr);
}
void ArrayClass::numSub(int arrdividend[],int tmparr[],int nfirst,int nlong)//计算和处理余数,这里各位不会出现负数
{
for(int t=nfirst+nlong+4;t>=nfirst;t--)
{
if(arrdividend[t] < tmparr[t])//要借位
{
arrdividend[t-1]=arrdividend[t-1]-1;
arrdividend[t]=arrdividend[t]+10;
}
arrdividend[t]=arrdividend[t]-tmparr[t];
}
}
int ArrayClass::compare(int arrdividend[],int tmparr[])//比较是否商过大了 或arrdividend > tmparr 返回1 arrdividend < tmparr 返回0
{
for(int i=1;i<MAX-1;i++)
{
if(tmparr[i] > arrdividend[i])return 0; //商大了
if(tmparr[i]<arrdividend[i]) return 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -