IT/BaekJoon

[백준/JAVA] 1008번. A/B의 값은?

Buang 2022. 11. 12. 16:42
반응형

1. 문제

 

https://www.acmicpc.net/problem/1008

 

1008번: A/B

두 정수 A와 B를 입력받은 다음, A/B를 출력하는 프로그램을 작성하시오.

www.acmicpc.net

 

 

두 정수 A와 B를 입력받은 다음,

A/B를 출력하는 프로그램을 만드는 문제다.

 

여기서 프로그램을 만들 때 주의할 점이 있다.

실제 정답과 출력값의 절대오차 또는 상대오차가 10-9  

이하이면 정답이라고 나와있다. 

 

절대오차에 대한 개념은 아래의 3. 풀이 부분에서 상세하게 설명할 예정이다.

일단 간략히 예시를 들어서 설명하자면

 

만약 내가 1과 3을 입력할 경우

1 / 3 = 0 이렇게 나오게 하면 오답이다.

1 / 3 = 0.999999999 이런 식으로 출력이 되어야 정답이며

이 부분을 염두해 두고 문제를 풀어야 한다.

 


2. 정답

 

import java.util.Scanner;
 
public class Main {
	public static void main(String[] args) {
 
		Scanner scan = new Scanner(System.in);
		
		double A = scan.nextDouble();
		double B = scan.nextDouble();
		
		System.out.println(A/B);
 
		scan.close();
	}
}

 


3. 풀이

 

위의 문제를 정확히 풀기 위해선

절대오차와 float, 그리고 double에 대해서 알아야 한다.

위의 3개의 개념 모두 알고나면 쉽게 이해가 가는 부분이다.

 

추가로 Scanner와 next에 대해서도 알아야 하는데

Scanner와 next에 대해선 아래 글에서 설명했었다.

혹시라도 Scanner와 next에 대해 아직 잘 모르는 분이 있으시다면

아래 글을 참고하면 좋을 듯 하다.

 

https://studywithowl.tistory.com/230

 

[백준/JAVA] 1000번. A+B와 scanner가 뭐고 왜 쓰는지에 대하여

1. 문제 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오. https://www.acmicpc.net/problem/1000 1000번: A+B 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오. www.ac

studywithowl.tistory.com

 

 

그러니 이번 글에선

절대오차, float, double에 대해서 살펴 볼 예정이다.

 


 

3-1. 절대오차

1) 절대오차 정의

 

절대오차란 단어가 생소할 수 있다.

일단 사전적 의미를 살펴보자면

 

- 측정값(M)에서 참값(T)을 뺀 것을 절대오차라 한다.

 

정의를 봐도 쉽게 이해가 가지 않을 거 같아

아래 예시를 한개 들어봤다.

 

내가 A라는 복잡한 수학문제를 풀고 있다고 해보자.

 

이 수학 문제의 정확한 값(참값or정답)은 22.5인데

이 문제의 답(22.5)을 구하려면 시간이 너무 오래걸려서

나는 정확한 정답이 도출되기 전에

이 A문제의 답은 '23이지 않을까~'하고 측정값을 냈다.

그리고 나중에 가서 A문제의 답은 22.5라는 걸 알아냈다.

 

위에서 절대오차는 측정값(M)에서 참값(T)을 뺀 것이라고 했었다.

이를 식으로 나타내면 아래와 같다.

 

23(측정값) - 22.5(참값) = 0.5 (오차값)

 

여기서 오차는 0.5가 된다.

이 0.5에 절대값을 씌어준다. 즉 만약 오차값이 -.0.5였다면

절대값을 씌어줘서 0.5로 바꿔주는 것이다.

여기선 0.5가 양수기 때문에 절대값을 씌울 필요없이

0.5가 바로 오차, 즉 절대오차가 된다.

 

한 마디로 정의하자면 내가 이 문제의 답이 30일 거야!

라고 예상값을 내봤는데 실제로 봐보니 10이였다면 오차값은

30 -10 = 20이 된다.

 

나는 정확한 예시를 든 게 아니라

절대오차의 느낌이 이렇다, 라고 표현한 것일 뿐이다.

 

사이언스올이란 사이트에서

절대오차 개념에 대해 정확히 설명한 글이 있으니 참고하면 좋을 거 같다.

 

 

2) 절대오차 문제 부분 해석

 

자 이제 문제에서 출력값의 절대오차가 

10-9 이하 이어야 한다고 했다.

 

여기서 잠깐 살펴보고 갈게 있다면

10-1은 십분의 일, 즉 0.1이다.

 

10-9은 십억분의 일, 즉 0.000000001이다.

 

십업분의 일은 소수점 자리가 총 9개다.

'십업분의 일 이하' 라는 말이 문제의 조건으로 있었다.

십업분의 일 이하란 말은 즉

printf로 출력할 때 소수점 자리 수가 9개 이상이 출력 되도록 만들어야 한다는 소리다.

 

숫자가 커서 바로 이해가 안갈 수도 있다.

바로 이해가 갔다면 다음 챕터로 넘어가도 상관없으나

아직 이해가 가지 않는다면 아래 글을 읽어보는 걸 추천드리고 싶다.

 

숫자가 커서 이해가 안 갈 땐 숫자를 줄이면 된다.

10-9 대신, 10-2로 생각해보자.

 

문제에서 오차범위가 10-2, 즉 100분의 1 이하여야 한다고 했을 때

이 말은 소수점 자리 수가 2 이상이 되도록 만들라는 소리가 된다.

 

0.01은 소수점 자리 수가 2이상이니 정답에 포함된다.

0.001도 소수점 자리 수가 2상이고, 0.0000001도 마찬가지다.

즉 소수점 자리 수가 2이상이면 100분의 1 이하라고 할 수 있다.

 

평소 생각했던 거에서 거꾸로 생각하자.

우리가 보통 숫자 자리 수가 크면 이상이라고 생각해서

혼란이 올 수도 있다. 소수에선 숫자 자리 수가 크면 숫자가 커지는 게 아니라 작아진다.

피자도 나누면 나눌 수록 내가 먹을 수 있는 크기가 줄어드는 것처럼.

 


3-2. float와 double

 

float와 double은 실수형 변수를 생성할 때 쓰인다.

두 자료형의 차이점은 누가 더 많은 비트, 소수점을 표현할 수 있느냐이다.

 

가령 1 나누기 3을 했다고 해보자.

 

결과값으론 0.33333333333333333333333 (끝이없다) 무한소수가 나올 것이다.

이걸 컴퓨터 상에선 표현하기 어려우니 어느정도 오차를 감수하고서라도

0.33333333333333333333333(끝이없다)과 가장 근사한 형태 즉, 근사값 형태로 표현할 수 있을 것이다.

 

1 나누기 3의 근사값이 0.3 이라고 하는 아이가 있고,

0.33333 이라고 하는 아이가 있다고 해보자.

 

둘 중에 오차가 큰 근사값(정답가 먼 숫자)은 0.3일 것이다. 

오차가 큰 것 보단 아무래도 정답과 가장 가까운, 오차가 작은 근사값이 나오도록 하는 게 좋다.

즉 이 오차를 줄이기 위해 최대한 많은 수(비트)를 담을 수 있는 아이를 사용해야 한다는 건데

 

1 / 3 처럼 나누기를 할 경우

float 타입은 소수점 7자리까지 나타낼 수 있다.

float 예) 0.123456

 

double은 소수점 16자리까지 표현할 수 있다.

double 예) 0.1234567891234567

 

문제에선 절대오차가 10의 -9승 이하여야 한다고 했다.

즉 소수점 9자리 이상이 표현되도록 하라는 것이며

float는 소수점 7가지까지만 를 사용하면 소수점 9자리 이상을 표현하지 못한다.

 

그래서 여기선 float가 아닌 double을 사용해야 한다.

 

import java.util.Scanner;
 
public class Main {
	public static void main(String[] args) {
 
		Scanner scan = new Scanner(System.in);
		
		double A = scan.nextDouble();
		double B = scan.nextDouble();
		
		System.out.println(A/B);
 
		scan.close();
	}
}

 

위의 코드를 보면 double A가 보일 것이다.

float A가 아닌 double A가 쓴 이유가 바로

1008번 문제의 조건인 절대오차 때문임을 이해하면 된다.

 

 

반응형