Develop
2003.04.23 11:14
[c] 분수계산 함수^^
Views 10144 Comment 0
분수를 계산하는 함수.
최대공약수를 구하는 기능을 하는 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 와 같이 써야한다.
No. | Category | Subject | Author | Date | Views |
---|---|---|---|---|---|
589 | Develop | [php] GregorianToJD(), JDToGregorian() 함수 내용 | hooni | 2013.12.25 | 10643 |
588 | Develop | [php] 날짜 정보 출력 (년,월,일,시,분,초) | hooni | 2013.04.23 | 10584 |
587 | Develop |
최근 논문 자료 (2011/01/03, 만현형한테 보낸거..)
![]() |
hooni | 2013.04.23 | 10366 |
586 | Develop | [c] OpenGL 임시로 여기 올림.. | hooni | 2003.04.23 | 10349 |
585 | Develop |
[c++] Window API(MFC) 오목 게임
![]() |
hooni | 2003.04.23 | 10322 |
584 | Develop |
[java] 입출력 스트림 2부 (바이트)
![]() |
hooni | 2013.04.23 | 10315 |
583 | Develop |
[php] Laravel 5.4: Specified key was too long error
![]() |
hooni | 2017.12.04 | 10300 |
582 | Develop | [c] pcap을 이용한 패킷 분석 ㅎㅎ | hooni | 2003.04.23 | 10253 |
581 | Develop |
[c] 그래픽스 자료(OpenGL 라이브러리) 샘플 소스
![]() |
hooni | 2003.04.23 | 10216 |
580 | Develop |
[c] 최단거리 알고리즘 & 예제소스..
13 ![]() |
hooni | 2013.04.23 | 10211 |
579 | Develop |
[c] 간단한 자료구조(stack, queue, linked list) 구현 소스
6 ![]() |
hooni | 2003.04.23 | 10170 |
578 | Develop | [c++] p.47 연습문제 3번 | hooni | 2003.04.23 | 10150 |