알고리즘을 풀다 보면
이 문제와 같이
"출력값의 절대오차 또는 상대오차가 10^-9 이하이면 정답"
라는 조건이 달린 문제를 많이 볼 수 있다.
이번 글에서는 오차, 절대 오차, 상대 오차에 대해 알아본 후해당 문제를 풀이할 것이다.
오차(Error)
오차란 참값(또는 이론값)과 실제 측정값(또는 근삿값) 사이의 차이를 의미한다.
굳이 식으로 본다면 다음과 같이 볼 수 있다.
오차 = 측정값 또는 근삿값 − 참값 (실제 값)
절대 오차(Absolute Error)
절대 오차란 참값과 근삿값의 차이를 절댓값으로 취한 것을 의미한다.
식으로 예를 들면 다음과 같이 볼 수 있다.
참값 = 3.14159265
근삿값 = 3.14
절대 오차 = ∣근삿값 − 참값∣= 0.00159265
이걸 또 다르게 표현하면 0.00159265 ≈ 1.59 * 10^-3 이기 떄문에
절대 오차가 10^-3 (1/1000)이다. 라고 표현할 수 있다.
상대 오차(Relative Error)
상대 오차란 절대 오차와 참값을 나눈 것을 의미한다.
식으로 예를 들면 다음과 같이 볼 수 있다.
상대 오차 = 절대 오차/참값
= 0.000506 ≈ 5.06 * 10^-4 ≈ 10^-4
상대 오차(%) = 상대 오차 * 100 = 0.0506%
이렇게 나타낼 수 있다.
백준 1008 문제 풀이
우리가 흔히 문제를 풀 때는 절대 오차가 계산하기 쉽기 때문에
절대 오차를 즐겨 사용한다.
혹시나 모르는 분들을 위해 말씀드리자면
10^-n은 10^n을 역수 취하면 된다. (1/10^n)
문제에서 절대, 상대 오차 10^-9이하로 해달라고 했기 때문에
대략 10^-10 즉, 소수점 10번째 자리까지 넉넉히 출력해 주면 된다.
여기서 주의해야 할 점이 부동소수점 자료형마다
표기할 수 있는 소수점 자릿수가 제한이 있다.
다음 표를 참고 하면
자료형 | 바이트 수 | 십진수 유효 자릿수 | 소수점 유효 자릿수 |
float | 4 | 약 7자리 | 약 7자리 |
double | 8 | 약 16자리 | 약 16자리 |
long double | 8 이상 | 약 19자리 | 약 19자리 |
이런 식으로 제한이 있기 때문에 해당 문제에서는
double 혹은 long double을 이용해 풀어야 한다.
다음은 정답 코드이다.
#include <iostream>
#include <iomanip>
int main(int argc, char *argv[]) {
double a, b;
std::cin >> a >> b;
std::cout << std::fixed << std::setprecision(10) << a/b;
return 0;
}
여기서 set::setprecision()만 쓰면 전체 유효 숫자 10자리까지만 출력하고
std::fixed << std::setprecision() 이런 식으로 fixed와 같이 쓰면
소수점 아래 10자리까지 출력하게 된다.
#include <iostream>
int main(int argc, char *argv[]) {
double a, b;
scanf("%lf %lf", &a, &b);
printf("%.10f", a/b);
return 0;
}
C 스타일로 하면 이렇게 적을 수 있으며
%. 뒤 숫자가 자리수를 지정한다.
C 스타일로 long double를 입력 받을 때는
long double x;
scanf("%Lf", &x);
이렇게 쓰면 된다.
마무리
오늘도 제 부족한 글 봐주셔서 감사합니다.
틀린 사항이 있다면 댓글로 달아주세요
바로 반영하겠습니다~!