//BigLong.h
#pragma once
class CBigLong
{
public:
CBigLong(const char*);
~CBigLong(void);
const char* GetValue()const;
CBigLong& operator+( const CBigLong&);
CBigLong& operator-( const CBigLong&);
CBigLong& operator*( const CBigLong&);
CBigLong& operator/( const CBigLong&);
CBigLong& operator=( const CBigLong&) ;
private:
char *value;
int GetAddData(int ,int *);
char* DataVer(const char *) ;
int chcBig( char* data1,char* data2);
char* addZore(int length,const char*);
char* removeZore(int length,const char*);
void AddStart(const char* str1,const char* str2,char*returnValue);
char* DelPreStr(char* data,int length);
char* tryProess(char* data1,char* data2);
};
//BigLong.cpp
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "BigLong.h"
CBigLong::CBigLong(const char* _value)
{
value = new char[strlen(_value)+1];
memset(value,0,strlen(_value));
strcpy( value, _value);
}
CBigLong::~CBigLong(void)
{
if(value!=NULL)
{
delete []value;
value = NULL;
}
}
//value を取得
const char* CBigLong::GetValue()const
{
return value;
}
//取得進位のデータ後の値
int CBigLong::GetAddData(int idata,int *addTemp)
{
int data = 0;
if( idata >= 10)
{
data = idata % 10;
*addTemp = idata / 10;
}else
{
data = idata;
*addTemp = 0;
}
return data;
}
//文字列の順番転換
char * CBigLong::DataVer(const char *data)
{
char *tem = new char[strlen(data)+1];
memset(tem,0,strlen(data)+1);
for( int i = strlen(data)-1,j=0;i >= 0 ; i--,j++)
{
tem[j] = data[i];
}
return tem;
}
void CBigLong::AddStart(const char* str1,const char* str2,char*returnValue)
{
int data =0;
int index =0;
int addTemp=0;
long chkNumBig = 0,chkNumSamll = 0;
char* bigStr,*smallStr ;
//データの大小のチェック
if( strlen(str1) > strlen(str2))
{
chkNumBig = strlen(str1);
chkNumSamll = strlen(str2);
bigStr = new char[chkNumBig+1];
smallStr= new char[chkNumSamll+1];
strcpy(bigStr,str1);
strcpy(smallStr,str2);
}
else
{
chkNumBig = strlen(str2);
chkNumSamll=strlen(str1);
bigStr = new char[chkNumBig+1];
strcpy(bigStr,str2);
smallStr = new char[chkNumSamll+1];
strcpy(smallStr,str1);
}
for(int i = 0,k = i; i < chkNumBig; i++,k++)
{
if( k > chkNumSamll -1)
{
int j;
for( j=i; j <= chkNumBig - 1 ; j++)
{
data = GetAddData(bigStr[j]-48 + addTemp,&addTemp);
returnValue[j] = data + 48;
index ++;
}
if(addTemp != 0)
{
returnValue[j] = addTemp+48;
addTemp = 0;
index ++;
}
break;
}
int tem = (bigStr[i]-48) + (smallStr[k]-48) + addTemp ;
data = GetAddData(tem,&addTemp);
returnValue[i] = data + 48;
index ++;
}
if(addTemp != 0)
{
returnValue[index] = addTemp+48;
addTemp = 0;
index ++;
}
returnValue[index] = '/0';
delete []bigStr;
delete []smallStr;
//return returnValue;
}
CBigLong& CBigLong::operator+(const CBigLong& bl)
{
int addTemp = 0;
int data =0;
const char* te = bl.GetValue();
char* blValue = this->DataVer(te);
char* newValue = DataVer(this->value);
unsigned long index = 0;
char returnValue[4996];
memset(returnValue,0,sizeof(returnValue));
AddStart(newValue,blValue,returnValue);
if( value != NULL)
{
delete []value;
value = NULL;
}
char* tempVar = DataVer(returnValue);
value = removeZore(strlen(tempVar),tempVar);
delete []tempVar;
delete []blValue;
delete []newValue;
return *this;
}
//大小のチェック
int CBigLong::chcBig( char* data1,char* data2)
{
if(strlen(data1) > strlen(data2))
{
return 1;
}else if(strlen(data1) < strlen(data2))
{
return -1;
}else
{
return strcmp(data1,data2);
}
}
//'0'の追加
char* CBigLong::addZore(int length, const char* data)
{
char* temp = new char[length + 1];
memset(temp,0,length + 1);
for(int i=0 ; i< length - strlen(data); i++)
{
temp[i] = '0';
}
strcat(temp,data);
return temp;
}
//'0'の削除
char* CBigLong::removeZore(int length, const char* data)
{
char* temp = new char[length + 1];
memset(temp,0,length + 1);
int j = 0,flag = 0,zoflag=0;
for(int i=0 ; i< length; i++)
{
if(data[i] == '-')
{
temp[j] = '-';
j++;
zoflag= 1;
}
else if(data[i] == '0' && flag ==0)
{
continue;
}
else //if(data[i] != '0' || flag ==1)
{
temp[j] = data[i];
j++;
zoflag= 1;
flag =1;
}
}
if(zoflag ==0)
{
temp[0] = '0';
}
return temp;
}
CBigLong& CBigLong::operator-( const CBigLong& bl)
{
int addTemp = 0;
int data =0;
const char* strSub = bl.GetValue();
char returnValue[4996];
memset(returnValue,0,sizeof(returnValue));
//BIG ,SMALLのチェック
int ck = chcBig(this->value,(char*)strSub);
int index = 0;
long chkNumBig = 0,chkNumSamll = 0;
char* bigStr,*smallStr ;
if( ck > 0)
{
chkNumBig = strlen(this->value);
chkNumSamll = strlen(strSub);
bigStr = new char[chkNumBig+1];
strcpy(bigStr,this->value);
smallStr = addZore(chkNumBig,strSub);
}
else
{
chkNumBig = strlen(strSub);
chkNumSamll=strlen(this->value);
bigStr = new char[chkNumBig+1];
strcpy(bigStr,strSub);
smallStr = addZore(chkNumBig,this->value);
}
for(int i = strlen(bigStr)-1; i >= 0; i--)
{
int intBig =bigStr[i] - 48;
int intSmall=smallStr[i] - 48;
if(intBig - addTemp >= intSmall)
{
//ここには&addTempがずっと0である
data = GetAddData( intBig - addTemp - intSmall ,&addTemp);
}else
{
intBig += 10;
data = GetAddData( intBig - addTemp - intSmall ,&addTemp);
addTemp = 1;
}
returnValue[index] = data + 48;
index++;
}
//------値のセット------------//
if( value != NULL)
{
delete []value;
value = NULL;
}
if( ck < 0){
returnValue[index] = '-';
}
char* tempVar= DataVer(returnValue);
value = removeZore(strlen(tempVar),(const char*)tempVar);
delete []tempVar;
delete []bigStr;
delete []smallStr;
return *this;
}
CBigLong& CBigLong::operator*( const CBigLong& bl)
{
int addTemp = 0;
int data =0;
unsigned long index = 0;
char* blValue = this->DataVer( bl.GetValue());
char* newValue = this->DataVer(this->value);
char* bigStr,*smallStr ;
int maxLength = 0,minLength = 0;
if(strlen(newValue ) > strlen(blValue))
{
maxLength = strlen(newValue);
minLength = strlen(blValue);
bigStr = new char[maxLength+1];
strcpy(bigStr,newValue);
smallStr= new char[minLength+1];
strcpy(smallStr,blValue);
}else
{
maxLength = strlen(blValue);
minLength = strlen(newValue);
bigStr = new char[maxLength+1];
strcpy(bigStr,blValue);
smallStr= new char[minLength+1];
strcpy(smallStr,newValue);
}
char* arrAdd = new char[255];
char* arrAddBack = new char[255];
memset(arrAddBack,0,255);
for(int i=0; i < minLength; i++)
{
memset(arrAdd,0,255);
int smallValue = smallStr[i] - 48;
int j;
for(j=0; j< maxLength; j++)
{
data = GetAddData((bigStr[j]-48) * smallValue + addTemp,&addTemp);
arrAdd[j] = data + 48;
}
if(addTemp != 0)
{
arrAdd[j] = addTemp + 48;
addTemp = 0;
}
if(strlen(arrAddBack) <= 0)
{
strcpy(arrAddBack, arrAdd);
continue;
}
char* tempZero = addZore( i + strlen(arrAdd),arrAdd);
AddStart(arrAddBack,tempZero,arrAddBack);
delete []tempZero;
}
if( value != NULL)
{
delete []value;
value = NULL;
}
this->value = DataVer(arrAddBack);
delete []arrAdd;
delete []arrAddBack;
delete []bigStr;
delete []smallStr;
delete []newValue;
delete []blValue;
return *this;
}
char* CBigLong::DelPreStr(char* data,int length)
{
char *retValue = new char[length];
return retValue;
}
char* CBigLong::tryProess(char* data1,char* data2)
{
char temp[255];
char* retValue = new char[255];
memset(retValue,0,255);
char tempData[255];
memset(tempData,0,255);
strcpy(tempData,data1);
int i=0,index = 1,dot =0;
while(1)
{
if(dot)
{
retValue[i] = '.';
dot = 0;
}
memset(temp,0,255);
memcpy(temp,tempData,index);
int flag = chcBig(temp,data2);
if( flag < 0 )
{
retValue[i] = 0 + 48;
index++;
i++;
continue;
}else if(flag == 0 )
{
retValue[i] = 1 + 48;
char * strDataT = DelPreStr(tempData,strlen(tempData) - index);
memset(tempData,0,255);
memcpy(tempData,strDataT,strlen(strDataT));
delete []strDataT;
index =1;
i++;
}else
{
//try data
for(int j = 9; j >= 1; j--)
{
char buff[3];
memset(buff,0,255);
itoa(j,buff,10);
CBigLong longL1(buff);
CBigLong longL2(data2);
longL1 = longL1 * longL2;
if(chcBig(longL1.GetValue(),temp) > 0)
{
continue;
}else
{
//値が得される
retValue[i] = j + 48;
// qiu yu
CBigLong longL3(temp);
CBigLong longL4 = longL3 - longL1;
char * strDataT = DelPreStr(longL4.GetValue(),strlen(longL4.GetValue()) - index);
memset(tempData,0,255);
sprintf(tempData,"%s%s",longL4.GetValue(),strDataT);
i++;
delete []strDataT;
break;
}
}
}
}
return retValue;
}
CBigLong& CBigLong::operator/( const CBigLong& bl)
{
int addTemp = 0;
int data =0;
unsigned long index = 0;
char retValue[4996] ;
memset(retValue,0,sizeof(retValue));
//char* blValue = this->DataVer( bl.GetValue());
//char* newValue = this->DataVer(this->value);
int flag = chcBig(this->value,(char*)bl.GetValue());
switch(flag)
{
case 1:
//i++;
break;
case -1:
break;
case 0:
break;
}
return *this;
}
CBigLong& CBigLong::operator=( const CBigLong& lbig)
{
const char* a = lbig.GetValue ();
strcpy(this->value,a);
return *this;
}
//测试程序
#include <stdio.h>
#include <string.h>
#include "BigLong.h"
void main()
{
printf("/t/t1: + /n");
printf("/t/t2: - /n");
printf("/t/t3: * /n");
printf("/t/t4: / /n");
printf("/t/t0: exit /n");
int slect;
char *a1=new char[255];
char *a2=new char[255];
while(1){
memset(a1,0,255);
memset(a2,0,255);
printf("please chose index:");
scanf("/t/t%d",&slect);
if(slect == 0)
{
return;
}
printf("please input data:/n");
printf("data 1:");
scanf("%s",a1);
printf("data 2:");
scanf("%s",a2);
CBigLong bigL(a1);
CBigLong big2(a2);
switch(slect){
case 1: //+
bigL = bigL + big2;
break;
case 2: //-
bigL = bigL - big2;
break;
case 3: //*
bigL = bigL * big2;
break;
case 4: ///
bigL = bigL / big2;
break;
}
printf(" %s/n",bigL.GetValue());
}
}