c·c++/c 프로그래밍

소수점이 포함된 큰수의 덧셈 뺄셈

바로이순간 2012. 6. 16. 09:34

#include <stdio.h>

#include <stdlib.h>

int compTwo(char a[], char b[]) {

    int i;

    i=0; 

    while(a[i]) {

        if(a[i]>b[i]) return 1;

        else if(a[i]<b[i]) return -1;

        i=i+1;

    }

    if(b[i]>0) return -1;

    return 0;

}

void addTwo(char a[], char b[], char c[]) {

// 소수점은 0번째 자리에 있지 않다고 가정하였다.

// 최소한 0.123 과 같이 시작하는 것으로 본다.

    int pos1, len1, intlen1, fraclen1;

    int pos2, len2, intlen2, fraclen2;

    int pos3, len3, intlen3, fraclen3;

    int dfrac;

    int i, j, x;


    i=0; 

    while(a[i]&&a[i]!='.') i=i+1;

    if(a[i]=='.') pos1=i; 

    else pos1=0;

    while(a[i]) i=i+1;

    len1=i; 

    if(pos1) intlen1=pos1; 

    else intlen1=len1; 

    fraclen1=len1-intlen1-1;

    //printf("len1=%d pos1=%d intlen1=%d fraclen1=%d\n", len1, pos1, intlen1, fraclen1);


    i=0; 

    while(b[i]&&b[i]!='.') i=i+1;

    if(b[i]=='.') pos2=i; 

    else pos2=0;

    while(b[i]) i=i+1;

    len2=i;

    if(pos2) intlen2=pos2; 

    else intlen2=len2;

    fraclen2=len2-intlen2-1;

    //printf("len2=%d pos2=%d intlen2=%d fraclen2=%d\n", len2, pos2, intlen2, fraclen2);


    if(fraclen1>=fraclen2) fraclen3=fraclen1;

    else fraclen3=fraclen2;

    if(intlen1>=intlen2) intlen3=intlen1;

    else intlen3=intlen2;

    intlen3=intlen3+1;

    if(fraclen3>0) len3=intlen3+fraclen3+1;

    else len3=intlen3;

    pos3=intlen3;

    c[0]=0;

    //printf("len3=%d pos3=%d intlen3=%d fraclen3=%d\n", len3, pos3, intlen3, fraclen3);


    if(fraclen1>=fraclen2) { 

        dfrac=fraclen1-fraclen2;

        i=0; 

        while(i<dfrac) { 

            c[len3-1-i]=a[len1-1-i]; 

            i=i+1; 

        } 

        x=0; 

        while(i<fraclen1) { 

            x=x+a[len1-1-i]+b[len2-1-i+dfrac]-'0'-'0'; 

            c[len3-1-i]='0'+(x%10); 

            x=x/10; 

             i=i+1; 

        }

    }

    else {

        dfrac=fraclen2-fraclen1;

        i=0; 

        while(i<dfrac) { 

            c[len3-1-i]=b[len2-1-i]; 

            i=i+1; 

        } 

        x=0; 

        while(i<fraclen2) { 

            x=x+a[len1-1-i+dfrac]+b[len2-1-i]-'0'-'0'; 

            c[len3-1-i]='0'+(x%10); 

            x=x/10; 

            i=i+1; 

        }

    }


    if(pos1==0) pos1=len1;

    if(pos2==0) pos2=len2;

    if(pos3==0) pos3=len3;    

    if(intlen1>=intlen2) {

        i=0; 

        while(i<intlen2) {

            x=x+a[pos1-1-i]+b[pos2-1-i]-'0'-'0'; 

            c[pos3-1-i]='0'+(x%10); 

            x=x/10; 

            i=i+1; 

        }

        while(i<intlen1) { 

            x=x+a[pos1-1-i]-'0'; 

            c[pos3-1-i]='0'+(x%10); 

            x=x/10; 

            i=i+1; 

        } 

    }

    else {

        i=0; 

        while(i<intlen1) {

            x=x+a[pos1-1-i]+b[pos2-1-i]-'0'-'0'; 

            c[pos3-1-i]='0'+(x%10); 

            x=x/10; 

            i=i+1; 

        }

        while(i<intlen2) { 

            x=x+b[pos2-1-i]-'0'; 

            c[pos3-1-i]='0'+(x%10); 

            x=x/10; 

            i=i+1; 

        } 

    }

    if(x) c[0]=x+'0';

    c[pos3]='.';

    if(c[0]==0) { 

        for(i=0;i<len3;++i) c[i]=c[i+1];

        len3=len3-1;

    }

    c[len3]=0;    

}

// subOne a가 b보다 크다는 것을 확인하고 호출하였다.

void subOne(char a[], char b[], char c[], int sign) {

// 소수점은 0번째 자리에 있지 않다고 가정하였다.

// 최소한 0.123 과 같이 시작하는 것으로 본다.

    int pos1, len1, intlen1, fraclen1;

    int pos2, len2, intlen2, fraclen2;

    int pos3, len3, intlen3, fraclen3;

    int dfrac;

    int i, j, x, y;


    i=0; 

    while(a[i]&&a[i]!='.') i=i+1;

    if(a[i]=='.') pos1=i; 

    else pos1=0;

    while(a[i]) i=i+1;

    len1=i; 

    if(pos1) intlen1=pos1; 

    else intlen1=len1; 

    fraclen1=len1-intlen1-1;

    //printf("len1=%d pos1=%d intlen1=%d fraclen1=%d\n", len1, pos1, intlen1, fraclen1);


    i=0; 

    while(b[i]&&b[i]!='.') i=i+1;

    if(b[i]=='.') pos2=i; 

    else pos2=0;

    while(b[i]) i=i+1;

    len2=i;

    if(pos2) intlen2=pos2; 

    else intlen2=len2;

    fraclen2=len2-intlen2-1;

    //printf("len2=%d pos2=%d intlen2=%d fraclen2=%d\n", len2, pos2, intlen2, fraclen2);


    if(fraclen1>=fraclen2) fraclen3=fraclen1;

    else fraclen3=fraclen2;

    if(intlen1>=intlen2) intlen3=intlen1;

    else intlen3=intlen2;

    intlen3=intlen3+1;

    if(fraclen3>0) len3=intlen3+fraclen3+1;

    else len3=intlen3;

    pos3=intlen3;

    c[0]=0;

    //printf("len3=%d pos3=%d intlen3=%d fraclen3=%d\n", len3, pos3, intlen3, fraclen3);


    if(fraclen1>=fraclen2) { 

        dfrac=fraclen1-fraclen2;

        i=0; 

        while(i<dfrac) { 

            c[len3-1-i]=a[len1-1-i]; 

            i=i+1; 

        } 

        x=0; 

        while(i<fraclen1) { 

            x=x+a[len1-1-i]-b[len2-1-i+dfrac];

            if(x<0) { x=x+10; y=-1; }

            else y=0; 

            c[len3-1-i]='0'+x; 

            x=y; 

            i=i+1; 

        }

    }

    else {

        dfrac=fraclen2-fraclen1;

        i=0;

        x=10; 

        while(i<dfrac) { 

            c[len3-1-i]=x-b[len2-1-i]+'0'+'0'; 

            i=i+1; 

            x=9;

        } 

        x=-1; 

        while(i<fraclen2) { 

            x=x+a[len1-1-i+dfrac]-b[len2-1-i]; 

            if(x<0) { x=x+10; y=-1; }

            else y=0;

            c[len3-1-i]='0'+x; 

            x=y; 

            i=i+1; 

        }

    }


    if(pos1==0) pos1=len1;

    if(pos2==0) pos2=len2;

    if(pos3==0) pos3=len3;    

    i=0; 

    while(i<intlen2) {

        x=x+a[pos1-1-i]-b[pos2-1-i]; 

        if(x<0) { x=x+10; y=-1; }

        else y=0;

        c[pos3-1-i]='0'+x; 

        x=y; 

        i=i+1; 

    }

    while(i<intlen1) { 

        x=x+a[pos1-1-i]-'0'; 

        if(x<0) { x=x+10; y=-1; }

        else y=0;

        c[pos3-1-i]='0'+x; 

        x=y; 

        i=i+1; 

    }

    c[pos3]='.';

    c[len3]=0;    

    i=0;

    while(c[i]==0||((c[i]==48)&&c[i+1]!='.')) i=i+1;

    x=i; 

    if(sign<0) { 

        c[x-1]='-';

        x=x-1;

    }

    for(i=0;i<len3+1;++i) c[i]=c[i+x];

}

void subTwo(char a[], char b[], char c[]) {

// 소수점은 0번째 자리에 있지 않다고 가정하였다.

// 최소한 0.123 과 같이 시작하는 것으로 본다.

    int pos1, len1, intlen1, fraclen1;

    int pos2, len2, intlen2, fraclen2;

    int pos3, len3, intlen3, fraclen3;

    int i, j, x;


    i=0; 

    while(a[i]&&a[i]!='.') i=i+1;

    if(a[i]=='.') pos1=i; 

    else pos1=0;

    while(a[i]) i=i+1;

    len1=i; 

    if(pos1) intlen1=pos1; 

    else intlen1=len1; 

    fraclen1=len1-intlen1-1;

    //printf("len1=%d pos1=%d intlen1=%d fraclen1=%d\n", len1, pos1, intlen1, fraclen1);


    i=0; 

    while(b[i]&&b[i]!='.') i=i+1;

    if(b[i]=='.') pos2=i; 

    else pos2=0;

    while(b[i]) i=i+1;

    len2=i;

    if(pos2) intlen2=pos2; 

    else intlen2=len2;

    fraclen2=len2-intlen2-1;

    //printf("len2=%d pos2=%d intlen2=%d fraclen2=%d\n", len2, pos2, intlen2, fraclen2);


    if(intlen1>intlen2) subOne(a, b, c, 1);

    else if (intlen1<intlen2) subOne(b, a, c, -1);

    else {

        x=compTwo(a,b);

        if(x>0) subOne(a, b, c, 1);

        else if(x<0) subOne(b, a, c, -1);

        else { c[0]='0'; c[1]=0; }

    }

}

// 여러가지 방식으로 출력을 바꾸기 위해서 임시로 만들어 둔 출력함수입니다.

void printOne(char a[], char format[]) {

    int i, j, len, frac, fixed, left, x, v;

    int pos, fraclen=0, length, dlength, shift=0, dshift;


    i=0; 

    while(a[i]&&a[i]!='.') i=i+1;

    if(a[i]=='.') pos=i; 

    else pos=0;

    if(pos>0) {

        fraclen=0;

        while(a[i]) {

            fraclen+=1;

            i=i+1;

        }

    }

    while(a[i]) i=i+1;

    length=i; 

    

    i=0;

    if(format[0]=='-') { 

        left=1;

        i=i+1;

    }

    else left=0;

    x=0;

    while((v=format[i])>0) {

        if(v<'0'||v>'9') break;

        x=10*x+v-'0';

        i=i+1;

    }

    len=x;

    //printf("i=%d format[i]=%d\n", i, format[i]);

    if(format[i]=='.') {

        x=0;

        i=i+1;

        while((v=format[i])>0) {

            if(v<'0'||v>'9') break;

            x=10*x+v-'0';

            i=i+1;

        }

        frac=x;

    }

    else frac=0;

    if(format[i]=='e') fixed=0;

    else fixed=1;

    //printf("left=%d len=%d frac=%d fixed=%d\n", left, len, frac, fixed);

    if(len<length+frac-fraclen) len=length+frac-fraclen;


    if(frac<fraclen) {

        if(a[pos+frac+1]>'4') {

            x=1;

            i=0;

            while(i<frac) { 

                x=x+a[pos+frac-i]-'0'; 

                a[pos+frac-i]='0'+(x%10); 

                x=x/10; 

                i=i+1; 

            } 

            if(a[pos+frac-i]=='.') i=i+1;

            while(i<pos+frac) { 

                x=x+a[pos+frac-i]-'0'; 

                a[pos+frac-i]='0'+(x%10); 

                x=x/10; 

                i=i+1; 

            } 

            if(a[0]=='-') {

                if(x>0) {

                    a[pos+frac+1]=0;

                    for(i=0;i<len+2;++i) a[len-i]=a[len-i-1];

                    a[0]='-'; a[1]='1';

                }

                 x=0;

            }

            else {

                x=x+a[0]-'0'; 

                a[0]='0'+(x%10); 

                x=x/10; 

                a[pos+frac+1]=0;

            }

            if(x>0) {

                for(i=0;i<len+2;++i) a[len-i]=a[len-i-1];

                a[0]='1';

            }

        }

    }

    if(fixed==1) {

        if(frac<fraclen) {

            if(a[pos+frac+1]>'4') {

                x=1;

                i=0;

                while(i<frac) { 

                    x=x+a[pos+frac-i]-'0'; 

                    a[pos+frac-i]='0'+(x%10); 

                    x=x/10; 

                    i=i+1; 

                } 

                if(a[pos+frac-i]=='.') i=i+1;

                while(i<pos+frac) { 

                    x=x+a[pos+frac-i]-'0'; 

                    a[pos+frac-i]='0'+(x%10); 

                    x=x/10; 

                    i=i+1; 

                } 

                if(a[0]=='-') {

                    if(x>0) {

                        a[pos+frac+1]=0;

                        for(i=0;i<len+2;++i) a[len-i]=a[len-i-1];

                        a[0]='-'; a[1]='1';

                    }

                    x=0;

                }

                else {

                    x=x+a[0]-'0'; 

                    a[0]='0'+(x%10); 

                    x=x/10; 

                    a[pos+frac+1]=0;

                }

                if(x>0) {

                    for(i=0;i<len+2;++i) a[len-i]=a[len-i-1];

                    a[0]='1';

                    length=length+1;

                }

            }

        }

        if(left==0) {

            printf("계산결과는");  

            for(i=0;i<len-length;++i) printf(" ");

            printf("%s", a);

        }

        else {

            printf("계산결과는");                

            printf("%s", a);

            for(i=0;i<len-length;++i) printf(" ");

        }

        printf("입니다.\n");

    }

    else {

        dlength=length;

        if(a[0]=='-') dlength=dlength-1;

        shift=fraclen+1-dlength;

        dshift=shift;

        if(dshift<0) dshift=-dshift;

        if(fraclen+1==dlength) {

            if(a[pos-1]=='0') {

                shift=1;

                i=pos+1; 

                while(a[i]>0) if(a[i++]=='0') shift+=1; else break;

                dshift=shift;

            }

        }

        //printf("left=%d len=%d frac=%d fixed=%d\n", left, len, frac, fixed);

        //printf("pos=%d fraclen=%d dlength=%d shift=%d\n", pos, fraclen, dlength, shift);

        if(shift<0) {

            for(i=0;i<dshift;++i) a[pos-i]=a[pos-1-i];

            a[pos+shift]='.';

            pos=pos+shift;

            fraclen=fraclen+dshift;

        }

        if(shift>0) {

            x=0; 

            if(a[0]=='-') x=1;

            a[x]=a[shift+1+x];

            i=x+2;

            while(a[i+shift]>0) {

                a[i]=a[i+shift];

                i=i+1;

            }

            a[i]=0;

            fraclen=fraclen+dshift;

            pos=x+1;

        }


        //printf("left=%d len=%d frac=%d fixed=%d\n", left, len, frac, fixed);

        //printf("pos=%d fraclen=%d dlength=%d shift=%d\n", pos, fraclen, dlength, shift);


        if(frac<fraclen) {

            if(a[pos+frac+1]>'4') {

                x=1;

                i=0;

                while(i<frac) { 

                    x=x+a[pos+frac-i]-'0'; 

                    a[pos+frac-i]='0'+(x%10); 

                    x=x/10; 

                    i=i+1; 

                } 

                if(a[pos+frac-i]=='.') i=i+1;

                while(i<pos+frac) { 

                    x=x+a[pos+frac-i]-'0'; 

                    a[pos+frac-i]='0'+(x%10); 

                    x=x/10; 

                    i=i+1; 

                } 

                if(a[0]=='-') {

                    if(x>0) {

                        a[pos+frac+1]=0;

                        for(i=0;i<len+2;++i) a[len-i]=a[len-i-1];

                        a[0]='-'; a[1]='1';

                    }

                    x=0;

                }

                else {

                    x=x+a[0]-'0'; 

                    a[0]='0'+(x%10); 

                    x=x/10; 

                    a[pos+frac+1]=0;

                }

                if(x>0) {

                    for(i=0;i<len+2;++i) a[len-i]=a[len-i-1];

                    a[0]='1';

                    length=length+1;

                }

            }

        }

        if(left==0) {

            printf("계산결과는");  

            for(i=0;i<len-length-4;++i) printf(" ");

            printf("%se%s%03d", a, (shift<=0?"+":"-"), dshift);

        }

        else {

            printf("계산결과는");  

            printf("%se%s%03d", a, (shift<=0?"+":"-"), dshift);

            for(i=0;i<len-length-4;++i) printf(" ");

        }

        printf("입니다.\n");

    }

}

int main () {

    char buf[100], format[100];

    char one[100]={0,}, two[100]={0,}, three[100]={0,};

    int i, j, x, y;


    printf("계산식을 입력하시오: \n");

    scanf("%s", buf);

    printf("출력형식을 입력하시오: ");

    scanf("%s", format);

    

    i=0;

    j=0;

    while(buf[i]>0) {

        one[j++]=buf[i++];

        if(buf[i]=='-'||buf[i]=='+') break;

    }

    if(buf[i]=='-') x=-1;

    else x=1;

    one[j]=0;

    j=0;

    i=i+1;

    while(buf[i]>0) {

        two[j++]=buf[i++];

    }

    two[j]=0;    


    //printf("buf=%s one=%s two=%s\n", buf, one, two);

    if(x>0)

        addTwo(one, two, three);

    else

        subTwo(one, two, three);

    

    printOne(three, format);

    printf("\n");

    system("Pause");


    return 0;

}

'c·c++ > c 프로그래밍' 카테고리의 다른 글

연결리스트  (0) 2012.06.24
정수의 비트표현, 정순과 역순  (0) 2012.06.16
연결리스트, 단어세기  (0) 2012.06.14
약수, 공약수, 최대공약수, 최소공배수  (0) 2012.06.14
중복된 단어 지우기  (0) 2012.06.14