PRACTICE/JAVA

[백준] 15792번 | A/B - 2

j1ngerhead 2024. 9. 25. 18:16

문제 링크

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

import java.io.*;
import java.util.*;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        StringBuilder sb = new StringBuilder();
		
        // ex ) A = 4, B = 5
        int A = Integer.parseInt(st.nextToken());
        int B = Integer.parseInt(st.nextToken()); 

        // 먼저 몫을 구하고 소수점을 추가
        sb.append(A / B + "."); // 4 / 5 = 0.8 -> 몫은 0, 결과는 "0."

        // 나머지를 10배하여 다음 계산을 준비
        A = 10 * (A - B * (A / B)); // 4 - 0 * 5 = 4 -> 4 * 10 = 40

        int T = 1500; // 소수점 아래 최대 1500자리까지 계산
        while (T-- > 0) {
            // 각 자리의 몫을 구하고 sb에 추가
            sb.append(A / B); // 40 / 5 = 8, 결과는 "0.8"
            // 나머지를 10배하여 다음 계산을 준비
            A = 10 * (A - B * (A / B)); // 40 - 8 * 5 = 0 -> 0 * 10 = 0

            // 나머지가 0이 되면 더 이상 계산할 필요 없음
            if (A == 0) break;
        }

        // 결과 출력
        System.out.println(sb.toString()); // "0.8" 출력
    }
}
  • 이 방식은 부동소수점의 제한을 피하고 정밀한 계산을 직접 구현하는 방법이다.
  • 정밀도 조절: 이 방법은 직접 자리수를 계산하기 때문에 소수점 이하 원하는 만큼의 자리수까지 정밀하게 계산할 수 있다.
  • StringBuilder 사용: 결과를 빠르게 이어 붙이기 위해 StringBuilder를 사용 → 많은 반복 작업에서 효율적
  • A == 0 조건: 계산 중간에 나머지가 0이 되면 더 이상 계산할 필요가 없으므로 루프 중단
T 변수 값 의미

 

1500이라는 숫자는 실제 문제를 해결하는 데 필요한 정밀도를 만족시키기 위해 설정된 임의의 값이다.

이 문제는 매우 높은 정밀도로 나눗셈 결과를 계산하는 방법을 묻고 있고 부동소수점 연산의 한계를 극복하기 위해 초등학교에서 배운 나눗셈 과정을 그대로 구현하였다. 1500이라는 값은 일반적으로 요구되는 정밀도보다 훨씬 높지만, 일부 테스트 케이스에서 필요할 수 있는 정밀도를 충분히 만족시키기 위해 선택한 값이다.

 

부동 소수점(Floating Point)


부동 소수점은 실수를 컴퓨터에서 표현하는 방식이다.
컴퓨터에서 실수를 표현할 때, 정수처럼 간단히 표현할 수 없기 때문에, 
소수점 위치를 "떠다니게(floating)" 하여 
보다 넓은 범위의 숫자를 표현할 수 있도록 설계된 방식이다.
'부동'이란 단어가 의미하는 것은 
소수점의 위치가 고정되어 있지 않고, '움직일 수 있다'는 것이다.
ㄴ 매우 큰 수나 매우 작은 수를 표현하는 데 유용

부동소수점의 한계
  1. 정밀도 제한: 부동소수점은 제한된 비트 수를 사용해 숫자를 표현하기 때문에, 매우 긴 소수점 이하 자리수를 정확하게 표현할 수 없다. 이는 특히 반복되지 않는 무한소수나 매우 작은 값을 표현할 때 문제가 된다.
  2. 오차: 부동소수점 계산은 근사치로 표현되기 때문에, 계산 결과에 약간의 오차가 발생할 수 있다. 예를 들어, 0.1을 여러 번 더할 때 결과가 1.0이 되지 않는 경우가 있을 수 있다.
  3. 표현 불가능한 숫자: 일부 숫자는 부동소수점 방식으로 정확하게 표현할 수 없다. 예를 들어, 0.1이나 1/3과 같은 숫자는 이진 부동소수점으로 정확히 표현할 수 없기 때문에 근사치로 저장된다.

부동소수점은 실수를 표현하고 계산할 때 사용되는 중요한 방법이지만

그 구조와 특성 때문에 일부 숫자는 정확하게 표현되지 못하며, 계산 결과에 미세한 오차가 발생할 수 있으니

정밀도가 매우 중요한 상황에서는 BigDecimal과 같은 대안적인 방식을 사용하여 정밀도를 높일 수 있다.

320x100

'PRACTICE > JAVA' 카테고리의 다른 글

[프로그래머스] 문자열을 정수로 바꾸기  (0) 2024.09.28
[프로그래머스] 약수의 합  (0) 2024.09.28
[백준] 4344번 | 평균은 넘겠지  (0) 2024.09.25
[토스NEXT] 멋쟁이 숫자  (1) 2024.09.25
[백준] 1924번 | 2007년  (1) 2024.09.24