상세 컨텐츠

본문 제목

문자열을 정수로(DWORD보다 큰)

프로그래밍/테크닉

by ∫2tdt=t²+c 2008. 7. 9. 00:31

본문

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;
    };
}

지저분하기 그지 없는 코드지만 어쩔수 없다.

관련글 더보기

댓글 영역