성공할 때 까지 무려 7번이나 틀린 문제.
별거 아니라고 얕봤다가... ㄷㄷ
문제는 cout.precision() 이었다.
이게 무엇인지, 문제가 무엇을 요구하는지 잘못 이해한 채로
무작정 화만 내면서 제출하니까 안 됐던 것.
문제의 출력 조건은 절대/상대 오차는 10^-9 까지 허용한다.
난 이걸보고 무작정 cout.precision(9); 을 쓰고 앉아있었다.
이건 문제를 잘못 이해한거다.
오차를 10^-9 까지 허용한다라고 함은,
소수점 아래 9번째 자리까지는 무조건 출력해야함. 10번째 자리부터는 오차로 인식.
그럼 cout.precision(int)는 무엇인가?
std library 안의 ios_base Class 에 속한 함수다.
(여기서 ios 란 그 사과사의 운영체제가 아닌 input output stream 일 것이다.)
그 기능은?
Specifies the number of digits to display in a floating-point number.
즉, 부동소수점의 몇번째 자리수까지 출력할지 정하는 함수.
그러나 중요한 부분은 parameter.
Parameters
_Prec
The number of significant digits to display, or the number of digits after the decimal point in fixed notation.
경우에 따라
소수점 아래수와는 상관없이 출력하고 싶은 유효숫자의 개수만을 지정할 수 있고,
또는 소수점 아래 몇번째 자리까지 출력할지를 정할 수 있는 것이다.
#include <iostream>
using namespace std;
int main()
{
double a, b;
cin >> a >> b;
// 절대/상대 오차는 10^-9까지 허용한다.
cout.precision(10);
cout << (a / b) << endl; // 유효숫자 개수 결정
cout << fixed << (a / b) << endl; // 소수점 아래 몇번째 자리까지 출력할지 결정
return 0;
}
1000000000/3 은 333333333.333333............이다.
첫번째 cout은 10개의 유효숫자만을 출력하면 되기 때문에
333333333.3 이 출력한다.
두번째 cout은 소수점 아래 10번째 자리까지 출력해야 되기 때문에
저런 결과가 나온다.
cout.precision(9); 이 왜 오류를 일으켰는지 궁금해져서
곰곰이 생각해봤다.
문제의 조건은 오차의 범위를 정해준 것이다. (10^-9)
그러니 소수점 아래 9번째 자리까지는 무조건 출력해야한다.
10번째 자리부터는 오차로 인식한다.
여기서 내가 틀린 이유가 나타났다.
10번째 자리 이하부터는, 얼마나 많이 출력되든간에 오차범위를 벗어나지 않는다.
0.099999999...가 절대 0.1이 될 수 없는 원리와 같다.
그래서 사실상, precision(n) 의 n은 10 이상이기만 하면 된다.
cout.precision(100); 도 해봤다. 잘 된다.
그럼 precision(9)은 왜 안 되냐?
아마 9번째 자리까지 출력하면,
우리가 인지하지 못하더라도 분명히 잘려나가는 부분이 있을 것이다.
버림이나 반올림이 될 수도 있고...등등.
'스페셜 저지' 문제인 이유가 있더라.
그리고 다른 블로거들이 올린 솔루션을 봤는데, fixed를 쓴 사람이 없었다.
문제의 조건을 고려하면 fixed를 쓰는게 정확하다고 본다.
(fixed를 안 써도 맞았다고 하긴 하더라. 왜 그런지는 모르겠다.)
'Training > BOJ' 카테고리의 다른 글
[C++] 11720 숫자의 합 (0) | 2020.07.20 |
---|---|
[C++] 2439 별 찍기 - 2 (0) | 2020.07.20 |
[C++] 15552 빠른 A+B (0) | 2020.07.20 |
[C++] 2741 N 찍기 (0) | 2020.07.18 |
[C++] 2839 설탕 배달 (0) | 2020.07.18 |