Contents

Develop
2003.04.23 11:14

[c] 분수계산 함수^^

조회 수 10055 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
분수를 계산하는 함수.
최대공약수를 구하는 기능을 하는 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
번호 분류 제목 글쓴이 날짜 조회 수
1173 System/OS 해커스랩 깨기.. 후후.. ㅋㅋ file hooni 2013.04.23 18408
1172 Etc 플라스터(Plaster) 수업 내용 secret hooni 2016.05.24 0
1171 Develop 프로그램 문서 관리 (Doxygen) hooni 2013.04.23 16383
1170 Develop 프로그래밍에서 foo, bar 함수의 유래 file hooni 2013.06.25 21237
1169 Develop 프로그래밍 소스 관련 사이트.. hooni 2013.04.23 16483
1168 Develop 페이팔에서 돈 찾기 (Paypal withdraw) file hooni 2014.02.20 10953
1167 Etc 티스토리 테이블 html,css 구문 hooni 2013.11.03 15939
1166 System/OS 콘솔에서 패스워드 걸린 zip 압축하는 명령 hooni 2018.03.02 923
1165 System/OS 컴파일러 수업 자료(교재 : 컴파일러 입문) file hooni 2003.04.23 21964
1164 Develop 캘리포니아 운전면허 족보 file hooni 2017.06.12 720
1163 Etc 캘리포니아 운전면허 문제 file hooni 2017.07.22 954
1162 Develop 최근 논문 자료 (2011/01/03, 만현형한테 보낸거..) secret hooni 2013.04.23 10366
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 98 Next
/ 98