首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

大整数运算 运算符重载 求前辈帮看下,该如何处理

2013-10-21 
大整数运算 运算符重载求前辈帮看下汇编成功,仅仅提示 strcpy 不安全***********************************

大整数运算 运算符重载 求前辈帮看下
汇编成功,仅仅提示 strcpy 不安全


*************************************  inf_int.h  ************************************


#ifndef _INF_INT_H_
#define _INF_INT_H_
#include <iostream>
#include<fstream>

using namespace std;
class inf_int
{
public :
    char* digits;
    int length;
    int thesign;   // true if positive , false if negative.
long *sl;

public :
    inf_int();               // assign 0 as a default value
inf_int(int){};
    inf_int(const char* );
    inf_int(const inf_int&); // copy constructor
~inf_int();             // destructor

    void  operator=(const inf_int&);                     // assignment operator
friend bool operator ==(const inf_int& , const inf_int&);
    friend bool operator !=(const inf_int& , const inf_int&);
    friend bool operator > (const inf_int& , const inf_int&);
    friend bool operator < (const inf_int& , const inf_int&);
    friend inf_int operator+(const inf_int& , const inf_int&); 
    friend inf_int operator-(const inf_int& , const inf_int&);
    friend inf_int operator*(const inf_int& , const inf_int&);
friend ostream& operator <<(ostream&,const inf_int&);
void setval(const char * s);                  //set the value
char * getval();                               //get the value
friend void regulator(inf_int *num);                 //carry  and borrow
friend void regulator_thesign(inf_int *num);          //set sign
friend void slToStr(inf_int *num);                  // array to string 
friend inf_int abs(const inf_int &);

   
};

#endif


**************************      inf_int.cpp     ************************************



#include "inf_int.h"
#include<cstring>
#include <stdlib.h>
#include <math.h>
using namespace std;

#define z1  "0"
#define z2  "00"
#define z3  "000"
#define z4  "0000"
#define R    10000


inf_int::inf_int()    //initialize constructor
{
thesign=true;
length=1;
sl=new long[length];
sl[0] =0;
digits=new char[30];
digits="0";
delete [] digits;
delete [] sl;
}
void inf_int::setval(const char * s)    //set the charactor value to object of inf_int
{
char THESIGN,temp[5];
int len,i,j=4,k=0;
THESIGN=s[0];
switch(THESIGN)
{
case '-':
case '+':
{
if(THESIGN=='-')thesign=false;                       //positive or negative
if(THESIGN=='+')thesign=true;
len=strlen(s);                              // storage the string value to digit
digits=new char[len+1];
strcpy(digits,s);
for(int n=0;n<=len;n++)digits[n]=digits[n+1]; //delete the sign
len=strlen(digits);
if (len%4==0) length=(int)len/4;
else length=(int)(len/4+1);
sl=new long[length];
for(i=len;i>=0;i--)//  asignment digits value to array value 4 digit convert to a long int.
{                                           //  
temp[j]=digits[i];
if(i==0&&j)
for(int q=0;q<j;q++)temp[q]='0';


if(j==0||i==0)
{
temp[4]='\0';                     
sl[k]=atol(temp);
j=4;k++;
}
                j--;

delete [] digits;
break;
}
default:
{
thesign=true;
len=strlen(s);
digits=new char[len+1];
strcpy(digits,s);
if (len%4==0) length=(int)len/4;
else length=(int)(len/4+1);
sl=new long[length];
for(i=len;i>=0;i--)
{
temp[j]=digits[i];
if(i==0&&j)
for(int q=0;q<j;q++)temp[q]='0';
if(j==0||i==0)
{
temp[4]='\0';
sl[k]=atol(temp);
j=4;k++;
}
                j--;
}
delete [] digits;
break;

}
}
}

inf_int::inf_int(const inf_int & a)         //copy constructor
{
int i;
thesign=a.thesign;
int n=strlen(a.digits);
digits=new char[n+1];
for(i=0;i<=n;i++)
digits[i]=a.digits[i];
length=a.length;
sl=new long[length];
for(i=0; i<length; i++)
sl[i]=a.sl[i];
delete [] digits;
delete [] sl;
}

inf_int::inf_int(const char * s)     //initialize 
{
setval(s);
}


char *  inf_int::getval ()   //get value by string type
{
char * temp,*e="-";
if(thesign==false)
{
temp=new char[strlen(digits)+2];
strcpy(temp,e);
strcat(temp,digits);
}
else
{
temp=new char[strlen(digits)+1];
strcpy(temp,digits);
}
return temp;
delete [] temp;
}



ostream& operator <<(ostream& fout,const inf_int&a)
{
fout<<a.digits;
return fout;
}

void inf_int::operator=(const inf_int &num)   // assignment operator

int i;
thesign=num.thesign;
int n=strlen(num.digits);
digits=new char[n+1];
for(i=0; i<=n; i++)
digits[i]=num.digits[i];          //copy num.digits  to inf_int digits
length=num.length;
sl=new long[length+1];
for(i=0 ; i<length; i++)
sl[i]=num.sl[i];
  delete [] sl;

}

 bool operator==(const inf_int& a , const inf_int& b)
 {
     // we assume 0 is always positive.
     if ( (strcmp(a.digits , b.digits)==0) && a.thesign==b.thesign )
         return true;
     return false;
 }

  bool operator!=(const inf_int& a , const inf_int& b)
 {
     if ( (strcmp(a.digits , b.digits)!=0) && a.thesign!=b.thesign )
         return true;
     return false;
 }

bool operator >(const inf_int& a , const inf_int& b)         //compare true or false
{
if(a.thesign >b.thesign ) return true;
if (a.thesign==true&&b.thesign==true)
{
if (strlen(a.digits) >strlen(b.digits) ) return true;
if ((strlen(a.digits) ==strlen(b.digits))&&(strcmp(a.digits ,b.digits )>0)) return true;
}
if (a.thesign==false&&b.thesign==false)
{
if (strlen(a.digits) <strlen(b.digits) ) return true;
if ((strlen(a.digits) ==strlen(b.digits))&&(strcmp(a.digits ,b.digits )<0)) return true;
}
return false;
}

bool operator <(const inf_int& a , const inf_int& b)
{
if(!(a.thesign>=b.thesign==true))
return true;
else 
return false;
}


void regulator(inf_int *num)   //set carry and borrow
{
   int i;
   for(i=0;i<num->length ;i++)
   {
   if(num->sl[i]>=R)   //set carry
   {
   num->sl[i+1]+=num->sl[i]/R;
   num->sl[i]%=R;
   }
   if(num->sl[i]<0)     //set borrow
   {
   num->sl[i+1]=num->sl[i+1]-1;
   num->sl[i]+=R;
   }
   }
}



void  regulator_thesign(inf_int *num)       //set the sign


{
int flag=1,i;
if(num->sl[num->length-1]<0)flag=-1;
num->thesign=flag*num->thesign;
for(i=0;i<num->length ;i++)num->sl[i]=flag*num->sl[i];
}

                                                       //set array value to digits
void slToStr(inf_int *num)
{
int i;
char * n_temp,*c_temp;
n_temp=new char[5];
c_temp=new char[5];
num->digits =new char[num->length *4+4];
num->digits[0]='\0';
i=num->length-1;
if(num->sl[i])  //highest bit
{
_ltoa(num->sl[i],n_temp,10);     //conver the long type to string type
strcpy(num->digits ,n_temp);
}
int l=0;
while(i)   //after set highest bit
{
i--;
_ltoa(num->sl[i],n_temp,10);       //conver the long type to string type
l=4-strlen(n_temp);
if(l>0)
{
if(l==1)strcpy(c_temp,z1); 
if(l==2)strcpy(c_temp,z2);
if(l==3)strcpy(c_temp,z3);
if(l==4)strcpy(c_temp,z4);
strcat(num->digits,c_temp);
}
strcat(num->digits,n_temp);
}
int len;
        while(num->digits[0]=='0')//  delete the invalid '0'of the high bit
        {
len=strlen(num->digits );
for(i=0;i<len; i++)
num->digits [i]=num->digits [i+1];
        }
  if(num->digits[0]=='\0')strcpy(num->digits,"0");
delete [] n_temp;
delete [] c_temp;
delete [] num->digits;
}



inf_int operator +(const inf_int& a , const inf_int& b)              //     + operation
{
int i;
inf_int temp;
temp.length =a.length>b.length ?a.length:b.length ;
if((a.length==b.length )&&abs((a.sl[a.length-1]*a.thesign+b.sl[b.length-1 ]*b.thesign ))>=R) ++temp.length ;
temp.sl=new long[temp.length ];
for(i=0;i<temp.length ;i++)temp.sl[i]=0;
for(i=0;i<temp.length ;i++)
{
if((i>=a.length)&&(b.length>a.length ))temp.sl[i]=b.sl[i]*b.thesign ;
if((i>=b.length )&&(a.length >b.length))temp.sl[i]=a.sl[i]*a.thesign;
    if((i<a.length)&&(i< b.length ))temp.sl[i]=a.sl[i]*a.thesign+b.sl[i]*b.thesign ;
    }
    regulator_thesign(&temp);
regulator(&temp);
slToStr(&temp);
return temp;
delete [] temp.sl;
}


inf_int operator -(const inf_int& a , const inf_int& b)            // -opration
{
inf_int temp,A;
        A=b ;
        A.thesign  *=false ;
temp=a+A;
return temp;
}


inf_int operator *(const inf_int& a , const inf_int& b)    //  * operation
{
int i,j;
inf_int temp;
temp.thesign =a.thesign*b.thesign ;
temp.length =a.length+b.length ;
temp.sl=new long[temp.length ];
for(i=0;i<temp.length ;i++)temp.sl[i]=0;
        for(i=0;i<a.length;i++)
{
for(j=0;j<b.length ;j++)
{
temp.sl[i+j]+= a.sl[i]*b.sl[j];
}
regulator(&temp);
}
slToStr(&temp);
return temp;
delete []temp.sl;
}

inf_int abs(const inf_int& num)//absolute
{
inf_int temp;
temp=num;
temp.thesign*=num.thesign;
return temp;
}


inf_int::~inf_int()
{
}




***********************   main.cpp ******************************


#include "inf_int.h"
#include <iostream>
#include <string.h>
#include <stdlib.h>

using namespace std;

int main()
{
cout<<"111111"<<endl;
inf_int a, e;
inf_int b(100);
inf_int c("321111111111122222222222233333333333444444444445555555555");
inf_int d("123451987651234572749499923455022211");
inf_int f=d;   // copy constructor
inf_int g(f);

a=b*c;

if (f==d) {
b=c-d;

cout << "a : " << a<< endl;
cout << "b : " << b<< endl;
cout << "c : " << c<< endl;


cout << "d : " << d<< endl;
cout << "e : " << e<< endl;
cout << "f : " << f<< endl;
cout << "g : " << g<< endl;
}

return 0;
}


[解决办法]
改用用strcnpy/strcpy_s
[解决办法]
运算符重载是语法糖。
语法糖越甜,编译调试查错越苦!

#include <iostream>
#include <string>
using namespace std;
inline int compare(string str1,string str2) {//相等返回0,大于返回1,小于返回-1
         if (str1.size()>str2.size()) return 1; //长度长的整数大于长度小的整数
    else if (str1.size()<str2.size()) return -1;
    else                              return str1.compare(str2); //若长度相等,则头到尾按位比较
}
string SUB_INT(string str1,string str2);
string ADD_INT(string str1,string str2) {//高精度加法
    int sign=1; //sign 为符号位
    string str;
    if (str1[0]=='-') {
        if (str2[0]=='-') {
            sign=-1;
            str=ADD_INT(str1.erase(0,1),str2.erase(0,1));
        } else {
            str=SUB_INT(str2,str1.erase(0,1));
        }
    } else {
        if (str2[0]=='-') {
            str=SUB_INT(str1,str2.erase(0,1));
        } else { //把两个整数对齐,短整数前面加0补齐
            string::size_type L1,L2;
            int i;
            L1=str1.size();
            L2=str2.size();
            if (L1<L2) {
                for (i=1;i<=L2-L1;i++) str1="0"+str1;
            } else {
                for (i=1;i<=L1-L2;i++) str2="0"+str2;
            }
            int int1=0,int2=0; //int2 记录进位
            for (i=str1.size()-1;i>=0;i--) {
                int1=(int(str1[i])-'0'+int(str2[i])-'0'+int2)%10;
                int2=(int(str1[i])-'0'+int(str2[i])-'0'+int2)/10;
                str=char(int1+'0')+str;
            }
            if (int2!=0) str=char(int2+'0')+str;
        }
    }
    //运算后处理符号位
    if ((sign==-1)&&(str[0]!='0')) str="-"+str;
    return str;
}
string SUB_INT(string str1,string str2) {//高精度减法
    int sign=1; //sign 为符号位
    string str;
    int i,j;
    if (str2[0]=='-') {
        str=ADD_INT(str1,str2.erase(0,1));
    } else {
        int res=compare(str1,str2);
        if (res==0) return "0";
        if (res<0) {
            sign=-1;
            string temp =str1;
            str1=str2;
            str2=temp;


        }
        string::size_type tempint;
        tempint=str1.size()-str2.size();
        for (i=str2.size()-1;i>=0;i--) {
            if (str1[i+tempint]<str2[i]) {
                j=1;
                while (1) {//zhao4zhong1添加
                    if (str1[i+tempint-j]=='0') {
                        str1[i+tempint-j]='9';
                        j++;
                    } else {
                        str1[i+tempint-j]=char(int(str1[i+tempint-j])-1);
                        break;
                    }
                }
                str=char(str1[i+tempint]-str2[i]+':')+str;
            } else {
                str=char(str1[i+tempint]-str2[i]+'0')+str;
            }
        }
        for (i=tempint-1;i>=0;i--) str=str1[i]+str;
    }
    //去除结果中多余的前导0
    str.erase(0,str.find_first_not_of('0'));
    if (str.empty()) str="0";
    if ((sign==-1) && (str[0]!='0')) str ="-"+str;
    return str;
}
string MUL_INT(string str1,string str2) {//高精度乘法
    int sign=1; //sign 为符号位
    string str;
    if (str1[0]=='-') {
        sign*=-1;
        str1 =str1.erase(0,1);
    }
    if (str2[0]=='-') {
        sign*=-1;
        str2 =str2.erase(0,1);
    }
    int i,j;
    string::size_type L1,L2;
    L1=str1.size();
    L2=str2.size();
    for (i=L2-1;i>=0;i--) { //模拟手工乘法竖式
        string tempstr;
        int int1=0,int2=0,int3=int(str2[i])-'0';
        if (int3!=0) {
            for (j=1;j<=(int)(L2-1-i);j++) tempstr="0"+tempstr;
            for (j=L1-1;j>=0;j--) {
                int1=(int3*(int(str1[j])-'0')+int2)%10;
                int2=(int3*(int(str1[j])-'0')+int2)/10;
                tempstr=char(int1+'0')+tempstr;
            }
            if (int2!=0) tempstr=char(int2+'0')+tempstr;
        }
        str=ADD_INT(str,tempstr);
    }
    //去除结果中的前导0
    str.erase(0,str.find_first_not_of('0'));
    if (str.empty()) str="0";
    if ((sign==-1) && (str[0]!='0')) str="-"+str;
    return str;
}
string DIVIDE_INT(string str1,string str2,int flag) {//高精度除法。flag==1时,返回商; flag==0时,返回余数
    string quotient,residue; //定义商和余数
    int sign1=1,sign2=1;
    if (str2 == "0") {  //判断除数是否为0
        quotient= "ERROR!";
        residue = "ERROR!";
        if (flag==1) return quotient;
        else         return residue ;


    }
    if (str1=="0") { //判断被除数是否为0
        quotient="0";
        residue ="0";
    }
    if (str1[0]=='-') {
        str1   = str1.erase(0,1);
        sign1 *= -1;
        sign2  = -1;
    }
    if (str2[0]=='-') {
        str2   = str2.erase(0,1);
        sign1 *= -1;
    }
    int res=compare(str1,str2);
    if (res<0) {
        quotient="0";
        residue =str1;
    } else if (res == 0) {
        quotient="1";
        residue ="0";
    } else {
        string::size_type L1,L2;
        L1=str1.size();
        L2=str2.size();
        string tempstr;
        tempstr.append(str1,0,L2-1);
        for (int i=L2-1;i<L1;i++) { //模拟手工除法竖式
            tempstr=tempstr+str1[i];
            tempstr.erase(0,tempstr.find_first_not_of('0'));//zhao4zhong1添加
            if (tempstr.empty()) tempstr="0";//zhao4zhong1添加
            for (char ch='9';ch>='0';ch--) { //试商
                string str;
                str=str+ch;
                if (compare(MUL_INT(str2,str),tempstr)<=0) {
                    quotient=quotient+ch;
                    tempstr =SUB_INT(tempstr,MUL_INT(str2,str));
                    break;
                }
            }
        }
        residue=tempstr;
    }
    //去除结果中的前导0
    quotient.erase(0,quotient.find_first_not_of('0'));
    if (quotient.empty()) quotient="0";
    if ((sign1==-1)&&(quotient[0]!='0')) quotient="-"+quotient;
    if ((sign2==-1)&&(residue [0]!='0')) residue ="-"+residue ;
    if (flag==1) return quotient;
    else         return residue ;
}
string DIV_INT(string str1,string str2) {//高精度除法,返回商
    return DIVIDE_INT(str1,str2,1);
}
string MOD_INT(string str1,string str2) {//高精度除法,返回余数
    return DIVIDE_INT(str1,str2,0);
}
int main() {
    char ch;
    string s1,s2,res;

    while (cin>>s1>>ch>>s2) {
        switch (ch) {
            case '+':res=ADD_INT(s1,s2);break;
            case '-':res=SUB_INT(s1,s2);break;
            case '*':res=MUL_INT(s1,s2);break;
            case '/':res=DIV_INT(s1,s2);break;
            case '%':res=MOD_INT(s1,s2);break;
            default :                   break;
        }
        cout<<res<<endl;
    }
    return(0);
}


[解决办法]
引用:
试过了,会提示 strcpy_s 不能包含两个参数。现在问题是整体可以汇编,但运行时会 叮 一声,然后 什么也不反映。


strcpy_s有两中形式的参数,一个是两个参数,一个是三个参数的,你用三个参数的试试

热点排行