Training/BOJ

[C++] 1008번 A/B

FATKITTY 2020. 7. 18. 11:22
반응형

 

성공할 때 까지 무려 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