Contents

Develop
2003.04.23 11:14

[c] 분수계산 함수^^

Views 10055 Comment 0
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print
분수를 계산하는 함수.
최대공약수를 구하는 기능을 하는 gcd() 함수를 이용하여 결과를 기약분수로 출력함.
나머지가 없을 때는 몫만 출력하고, 그 외 분자가 분모보다 크면 대분수로 출력함.

#include <stdio.h>
#include <conio.h>
#define swap(a,b) {a^=b;b^=a;a^=b;}

/* 두 수를 바꾸는 매크로 함수 */
void divside2(unsigned a,unsigned b,unsigned *m1,unsigned *m2,unsigned *m3);
unsigned gcd(unsigned a,unsigned b);

void main(){
    unsigned *x,*y,*z;    /* 포인터 변수 x, y, z 정의 */
    clrscr();
    divside2(655,225,x,y,z);    /* *x, *y, *z에 결과값이 저장된다. */

    if(*y==0 && *z==0) printf("%un", *x);     /* 나머지가 0일 경우 몫만 출력 */
    else if(!(*x)) printf("%u/%un", *y, *z);  /* 몫이 0일 경우 나머지만 분수로 출력 */
    else printf("%u %u/%un", *x, *y, *z);   /* 그 외의 경우 대분수 형태로 출력 */
}

/* 나누기를 분수로 계산하는 함수 - 포인터를 이용한 참조에 의한 호출 */
/* 음수는 취급하지 못한다.                                          */
void divside2(unsigned a,unsigned b,unsigned *m1,unsigned *m2,unsigned *m3){
    unsigned temp;        /* 최대공약수를 저장할 변수 */
    *m1=(unsigned)(a/b);     /* 나누기의 몫을 저장 */
    if(a%b==0) { *m2=0; *m3=0; return; }      

    /*  a/b의 나머지가 0인 경우  */
    temp=gcd(a%b, b);   

    /* 나머지의 분자와 분모의 최대공약수를 temp에 저장 */
    if(temp==1){    /* 최대공약수가 1외에 없는 경우 */
        *m2=(unsigned)(a%b);
        *m3=b;
    }else{    /* 최대공약수가 있으면 분자,분모를 최대공약수로 나눈다. */
        *m2=(unsigned)((a%b)/temp);
        *m3=(unsigned)(b/temp);
    }
}


/* 최대공약수를 구하는 함수 - 음수는 취급하지 못한다.  */
/* 리턴값 : 최대공약수                                 */
unsigned gcd(unsigned a,unsigned b){
    int m;
    if(b>a) swap(a, b);  /* a>b가 되게 한다. */

    while(1) {
        m=a-(unsigned)(a/b)*b;
        if(m==0) return b;        /* m==0이면 b가 최대공약수 */
        else if(m<0) return 1;  /* m<0이 되면 최대공약수는 1뿐 */
        else { a=b; b=m; }      /* 그 외의 경우 루프를 계속 돈다. */      
    }   /* while */
}


---------------------------------------------------
(설명) 

n0 = max( |a|, |b| )
n1 = min( |a|, |b| ) 
nk = nk-2 - [ nk-2 / nk-1 ] * nk-1

       k=2, 3, ...
만약 nk = 0 이면 최대공약수는 nk-1 이 된다.
---------------------------------------------------


이 함수들은 분수나눗셈을 하기위한 것이다. 
분수계산때 약분을 위해 최대공약수를 구하는 함수를 구현하였다. 
최대공약수를 구하는 원리는 다음과 같다. 

a, b의 절대값중에서 큰 수를 n0 에, 작은 수를 n1 에 대입한다. 
그리고 k를 2에서 하나씩 증가시키면서 계산하다가 nk 가 0이 되면 nk-1 이 최대공약수가 된다. 
만약 nk 가 0이 되지않고 음수가 되면 최대공약수는 1 외엔 없는 것이다. 
여기서 [a] 기호는 a 의 정수부분을 뜻한다. 


- gcd() 함수 : 
gcd() 함수는 최대공약수를 구하는 함수인데,
매개변수로 받은 두 수 a, b중 만약 b가 더 크면 두 수를 바꾸어 항상 a>b 인 상태로 만든다. 
여기서 swap()이라는 매크로 함수를 사용하였다. 
이 함수는 비트연산인 XOR을 이용한 것으로 프로그램 중간에 끼어 들어가므로 실행속도가 빠르다. 
다음으로 무한루프를 써서 m<=0 이 될 때까지 계속 계산식을 실행한다. 


- divside2() 함수 : 
이 함수는 unsigned형 변수 2개를 받아들여 몫, 나머지의 분자, 분모를 3개의 변수에 각각 저장한다. 
결과값은 포인터를 이용한 참조에 의한 호출을 이용한다. 
만약 나머지가 0이면 분자, 분모를 모두 0으로 반환한다. 
그러면 main()함수에서 이 경우를 처리해 몫만 출력하게 된다. 
두 수 a, b의 최대공약수가 1인 경우 분자에는 a%b가 대입되고, 분모에는 b가 그대로 대입된다. 
만약 최대공약수가 1이 아니면 분자, 분모를 최대공약수로 나눈다음 대입된다. 


- main() 함수 : 
나머지가 0인 경우 몫만 출력하고, 몫이 0이면 나머지만 분수로 출력한다. 
포인터를 이용하므로 printf() 함수의 실매개변수는 *x, *y, *z 와 같이 써야한다.


?

List of Articles
No. Category Subject Author Date Views
333 Algorithm 스터디 자료, 암호화에 대해서.. 나중에 볼 ppt.. file hooni 2013.04.23 13370
332 System/OS [ms-sql] 프로시져 예제.. file hooni 2013.04.23 13406
331 System/OS [linux] 쉘 스크립트에 대한 설명과 예제.. hooni 2003.04.23 13413
330 System/OS [linux] 프로그램 설치방법 (내공쌓기) hooni 2003.04.23 13433
329 Develop [c] 기본 자료형(int)이 표현할 수 없는 큰 수(Big number)를 덧셈하는 코드. 1 hooni 2013.04.23 13448
328 System/OS [linux] 간단한 vi편집기 사용 명령 hooni 2003.04.23 13456
327 System/OS [linux] 기존 환경설정 저장하면서 커널 컴파일.. hooni 2003.04.23 13458
326 System/OS [linux] 쉘 환경변수 PS1(프롬프트) hooni 2003.04.23 13492
325 Develop [c++] mfc 간단한 파일 입출력 예제 hooni 2013.04.23 13523
324 Develop [js] 자바스크립트를 동적으로 로딩하기 hooni 2013.04.23 13563
323 Develop [js] window.open() 속성 사용 방법 hooni 2013.11.18 13588
322 System/OS [linux] ipchains 옵션 hooni 2003.04.23 13611
Board Pagination Prev 1 ... 66 67 68 69 70 71 72 73 74 75 ... 98 Next
/ 98