DWORD보다 큰 정수를 더하는 코드는 전에 정리해놓았지만,
DWORD보다 큰 정수를 어떻게 입력받고, 출력하지??
방법은 단 한 가지, 문자열로 받고,문자열로 내보낸다.
그러기 위해서
double dabble이라는 알고리즘을 사용한다.
쉬프트 더하기 3 알고리즘이라고 카더라
long CreateFiString(Fi& fi,const char* number)
{
long Sign=0;
if(*number=='-')Sign=1,number++;
else if(*number=='+')number++;
DWORD len=(DWORD)strlen(number);
DWORD sn=(10*len+2)/3;
fi.Size=(sn+31)>>5;
DWORD i=(len+7)>>3;
fi.pData=new DWORD[fi.Size+i];
if(fi.pData==NULL)return -1;
DWORD*pdec=fi.pData+fi.Size;
memset(fi.pData,0,(fi.Size+i)<<2);
BYTE* pb=(BYTE*)(fi.pData+fi.Size);
for(i=len-1;(int)i>=0;)
{
*pb=number[i--]-'0';
if((int)i<0)break;
*pb|=(number[i--]-'0')<<4;
pb++;
}
for(i=0;i<(fi.Size<<5);i++)
{
_ilrsh1s32(fi.pData,(DWORD)((len+7)>>3)+fi.Size);
if((len<<2)>i)_ilg4ss3((BYTE*)pdec,(((DWORD)len<<2)-i+7)>>3);
}
if(Sign==1)Cmpl2SFi(fi);
while(fi.pData[fi.Size-1]==0)
{
if(fi.Size>1)if(fi.pData[fi.Size-2]&0x80000000)break;
fi.Size--;
}
fi.pData=(DWORD*)realloc(fi.pData,fi.Size<<2);
return 0;
}
여기서 Fi는 다음과 같이 정의되었다.
typedef struct tagFi
{
DWORD*pData;
DWORD Size;
}Fi;
두 인라인 함수는 다음과 같이 정의되었다.
inline DWORD _ilrsh1s32(DWORD *pdw,DWORD count)
{
DWORD dwCarry=0;
__asm{
push esi;
mov esi, pdw; //esi를 (char*)pdw로 지정
mov ecx, count;
dec ecx; //반복회수를 count-1로 지정
shr dword ptr[esi],1; //최하위더블워드 쉬프트
jnc rsh1s32carryb;
mov dwCarry,1; //올림처리
rsh1s32carryb:
add esi,4;
rsh1s32loop:
shr dword ptr[esi],1; //나머지 더블워드 쉬프트
jnc rsh1s32carry;
or dword ptr[esi-4h],0x80000000;
rsh1s32carry:
add esi,4;
loop rsh1s32loop; //반복
pop esi;
};
return dwCarry;
}
inline void _ilg4ss3(BYTE* pdw,DWORD count)
{
if(count==0)return;
__asm{
push esi;
push edi;
cld;
mov esi,pdw;
mov edi,esi;
mov ecx,count;
g4ss3loop:
lodsb;
mov ah,al;
shr ah,4;
and al,0x0F;
cmp al,8;
jl g4ss3dn;
sub al,3;
g4ss3dn:
cmp ah,8;
jl g4ss3dn2;
sub ah,3;
g4ss3dn2:
shl ah,4;
or al,ah;
stosb;
loop g4ss3loop;
pop edi;
pop esi;
};
}
지저분하기 그지 없는 코드지만 어쩔수 없다.
댓글 영역