Contents

Develop
2003.04.23 11:14

[c] 분수계산 함수^^

조회 수 10092 댓글 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
번호 분류 제목 글쓴이 날짜 조회 수
733 Develop macOS에 node, npm 설치하기 (homebrew) file hooni 2021.11.06 1433
732 Develop [php] 한글 문자열 자르기 (utf-8) hooni 2015.11.10 1437
731 Develop [android] 간단한 SQLIite 예제 hooni 2017.06.14 1441
730 Develop [ios] How to set up clang formatter hooni 2015.09.17 1461
729 Develop [ios] Swift 4 String, Date, DateFormatter 예제 hooni 2018.10.18 1497
728 Develop [swift] popToRoot 모달뷰, 네비게이션컨트롤러 한꺼번에 닫기 file hooni 2021.01.29 1538
727 Develop What is difference between Get, Post, Put and Delete? hooni 2018.02.28 1555
726 Develop How to Test SMTP AUTH using Telnet hooni 2018.04.05 1577
725 Develop [android] 레이아웃 사이즈 변경 (동적; programmatically) hooni 2016.11.07 1597
724 Develop [ios] binary를 C코드로 변환 file hooni 2015.01.03 1633
723 Develop [ios] 스크린 캡쳐 (전원버튼 + 홈버튼) 호출 알아내기 hooni 2014.11.19 1647
722 Develop [python] 파라미터 앞에 *, ** 의 의미? (*args, **kwargs) hooni 2019.11.22 1670
Board Pagination Prev 1 ... 5 6 7 8 9 10 11 12 13 14 ... 71 Next
/ 71