Thursday, March 29, 2007
Perl 펄] 소수를 분수로 변환 함수 구현; Decimal To Fraction Function
펄에서, 소수를 분수로 바꾸는 방법입니다. 아래의 decimalToFraction() 이라는 함수에 소수를 넣어주면, 분자 분모가 든 배열을 반환하는데, 이 배열을 printFraction() 이라는 함수에 넣어주면 화면에 분수 형태로 출력됩니다.
소수를 분수로 바꾸는 것은 구현하기 어렵고, 정밀도가 높은 소수의 경우에는 오차가 있어 그리 완벽하지는 않습니다.
스크립트 파일명: example.pl
(※ 스크롤 박스 사용법: 박스 안을 마우스로 클릭한 후, 키보드의 좌우 화살표키를 누르면 양옆으로 움직일 수 있습니다. 박스에서 다시 나오려면, 박스 바깥의 아무곳이나 클릭하면 됩니다.)
직접 구현하지 않고 CPAN 모듈을 사용하여 소수를 분수로 변환: ▶▶ [Perl/펄] 소수를 분수로 변환 / 분수를 소수로 바꾸기 - Math-Fraction
보다 정밀하게 소수를 분수로 변환하려면 매스매티카에서 계산하는 것이 좋습니다: ▶▶ 매스매티카] 소수를 분수로 변환 함수/명령; Mathematica Decimal To Fraction
소수 분수 상호 변환기: ▶▶ 소수 분수 변환기; 소수를 분수로, 분수를 소수로 변환; Frac Converter
소수를 분수로 바꾸는 것은 구현하기 어렵고, 정밀도가 높은 소수의 경우에는 오차가 있어 그리 완벽하지는 않습니다.
소수를 분수로 표현 예제 소스
스크립트 파일명: example.pl
(※ 스크롤 박스 사용법: 박스 안을 마우스로 클릭한 후, 키보드의 좌우 화살표키를 누르면 양옆으로 움직일 수 있습니다. 박스에서 다시 나오려면, 박스 바깥의 아무곳이나 클릭하면 됩니다.)
#!/usr/bin/perl
use strict; use warnings;
# 소수를 분수로 변환 (약분하여 출력)
print printFraction(decimalToFraction(0.5)), "\n"; # 1/2
print printFraction(decimalToFraction(0.1)), "\n"; # 1/10
print printFraction(decimalToFraction(1.1)), "\n"; # 11/10
print printFraction(decimalToFraction(3.44)), "\n"; # 86/25
print printFraction(decimalToFraction(3)), "\n"; # 3/1
print printFraction(decimalToFraction(0)), "\n"; # 0/1
print printFraction(decimalToFraction(5.4877325)), "\n"; # 1371933/250000
print printFraction(decimalToFraction(26.1245)), "\n"; # 52249/2000
print printFraction(decimalToFraction(2545.139)), "\n"; # 2545139/1000
print printFraction(decimalToFraction(0.25)), "\n"; # 1/4
print printFraction(decimalToFraction(0.42857142)), "\n"; # 428571/1000000 (=3/7)
print printFraction(decimalToFraction(0.3333333)), "\n"; # 333333/1000000
print printFraction(decimalToFraction(0.000071)), "\n"; # 71/1000000
# 파이값(원주율)을 분수로 변환
print printFraction(decimalToFraction(3.1415926535897932384626433832795)), "\n";
# 3141593/1000000
# 소수를 분수로 변환 함수
sub decimalToFraction {
my $iP = int($_[0]); # 소수의 정수부만 구하기
my $fP = $_[0] - int($_[0]); # 소수의 소수부만 구하기
$fP = RoundXL($fP, 6); # 소수부의 정밀도가 지나치게 높지 않게끔 반올림
my $bunmo = 10 ** (length($fP) - 2); # 소수점 이하 자릿수만큼 분모 만들기: 가령 0.001 은 1000 으로
return reduceFraction(($iP + $fP) * $bunmo, $bunmo); # 약분 후, 분자, 분모 반환
}
# 분수를 알아보기 쉽게 출력하는 함수
# 분수의 구성 요소가 든 배열을 분수로 출력
sub printFraction {
return $_[0], "/", $_[1];
}
# 분수 약분 함수 (Reduce a Fraction)
# 분자 분모를 입력받아, 약분 후, 분자 분모가 든 배열을 반환
sub reduceFraction {
my @frac = @_;
if ($frac[1] == 0) { return "NaN", "NaN"; } # 분모가 0일 경우에 에러 반환
my $gcd = gcd(@frac);
return ($frac[0] / $gcd, $frac[1] / $gcd);
}
# 최대 공약수 계산 함수
sub gcd {
my $a = $_[0];
my $b = $_[1];
while ($b != 0) {
my $temp = $a % $b;
$a = $b;
$b = $temp;
}
return abs($a);
}
# 실수를 실수로, 지정한 자릿수에서 반올림 함수
sub RoundXL {
sprintf("%.$_[1]f", $_[0]);
}
use strict; use warnings;
# 소수를 분수로 변환 (약분하여 출력)
print printFraction(decimalToFraction(0.5)), "\n"; # 1/2
print printFraction(decimalToFraction(0.1)), "\n"; # 1/10
print printFraction(decimalToFraction(1.1)), "\n"; # 11/10
print printFraction(decimalToFraction(3.44)), "\n"; # 86/25
print printFraction(decimalToFraction(3)), "\n"; # 3/1
print printFraction(decimalToFraction(0)), "\n"; # 0/1
print printFraction(decimalToFraction(5.4877325)), "\n"; # 1371933/250000
print printFraction(decimalToFraction(26.1245)), "\n"; # 52249/2000
print printFraction(decimalToFraction(2545.139)), "\n"; # 2545139/1000
print printFraction(decimalToFraction(0.25)), "\n"; # 1/4
print printFraction(decimalToFraction(0.42857142)), "\n"; # 428571/1000000 (=3/7)
print printFraction(decimalToFraction(0.3333333)), "\n"; # 333333/1000000
print printFraction(decimalToFraction(0.000071)), "\n"; # 71/1000000
# 파이값(원주율)을 분수로 변환
print printFraction(decimalToFraction(3.1415926535897932384626433832795)), "\n";
# 3141593/1000000
# 소수를 분수로 변환 함수
sub decimalToFraction {
my $iP = int($_[0]); # 소수의 정수부만 구하기
my $fP = $_[0] - int($_[0]); # 소수의 소수부만 구하기
$fP = RoundXL($fP, 6); # 소수부의 정밀도가 지나치게 높지 않게끔 반올림
my $bunmo = 10 ** (length($fP) - 2); # 소수점 이하 자릿수만큼 분모 만들기: 가령 0.001 은 1000 으로
return reduceFraction(($iP + $fP) * $bunmo, $bunmo); # 약분 후, 분자, 분모 반환
}
# 분수를 알아보기 쉽게 출력하는 함수
# 분수의 구성 요소가 든 배열을 분수로 출력
sub printFraction {
return $_[0], "/", $_[1];
}
# 분수 약분 함수 (Reduce a Fraction)
# 분자 분모를 입력받아, 약분 후, 분자 분모가 든 배열을 반환
sub reduceFraction {
my @frac = @_;
if ($frac[1] == 0) { return "NaN", "NaN"; } # 분모가 0일 경우에 에러 반환
my $gcd = gcd(@frac);
return ($frac[0] / $gcd, $frac[1] / $gcd);
}
# 최대 공약수 계산 함수
sub gcd {
my $a = $_[0];
my $b = $_[1];
while ($b != 0) {
my $temp = $a % $b;
$a = $b;
$b = $temp;
}
return abs($a);
}
# 실수를 실수로, 지정한 자릿수에서 반올림 함수
sub RoundXL {
sprintf("%.$_[1]f", $_[0]);
}
직접 구현하지 않고 CPAN 모듈을 사용하여 소수를 분수로 변환: ▶▶ [Perl/펄] 소수를 분수로 변환 / 분수를 소수로 바꾸기 - Math-Fraction
보다 정밀하게 소수를 분수로 변환하려면 매스매티카에서 계산하는 것이 좋습니다: ▶▶ 매스매티카] 소수를 분수로 변환 함수/명령; Mathematica Decimal To Fraction
소수 분수 상호 변환기: ▶▶ 소수 분수 변환기; 소수를 분수로, 분수를 소수로 변환; Frac Converter
tag: perl
Perl | 펄
tag: study
학습 | Study
<< Home