Develop
2003.04.23 11:14
[c] 분수계산 함수^^
조회 수 10240 댓글 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 와 같이 써야한다.
-
[js] 초간단 암호화/복호화 소스..
-
[c/c++] Makefile 사용하기.. ㅋㅋ
-
[linux] tar 명령어 뽀개기.. ㅋㅋ
-
[c] 문자열 뒤집기 (문자열 거꾸로 출력하는 간단소스)
-
[c] 날짜로 요일 찾기..
-
[c] 캘린더 양음 변환 함수
-
[c] 소수 구하기 #1 (한정된 숫자 내에 있는 소수 걸러내기)
-
[c] 분수계산 함수^^
-
[c] 반올림 함수!! ㅋㅋ
-
[c] 스택/힙 오버플로우 테스트(overflow)
-
[c] 지나가는 패킷 잡기
-
[c] ICMP 패킷을 이용한 장난감