본문 바로가기

프로그래밍 언어/Java

Java 실수형(Floating-Point) 데이터 타입: 정밀도, 연산, 오차 해결 방법

Java 실수형(Floating-Point) 데이터 타입: 정밀도, 연산, 오차 해결 방법

Java에서 실수를 다룰 때는 floatdouble 두 가지 주요 데이터 타입을 사용합니다. 그러나 실수 연산은 정수 연산과 다르게 정밀도 문제, 연산 오차 등의 문제가 발생할 수 있습니다. 이 글에서는 Java의 실수형 데이터 타입의 특징을 이해하고, 이를 활용하는 방법과 발생할 수 있는 오류를 해결하는 방법을 상세히 살펴보겠습니다.

 

 

목차

  1. Java의 실수형 데이터 타입 개요
  2. float vs. double: 차이점 비교
  3. 실수 연산에서 정밀도 문제
  4. 실수형 데이터의 연산과 주의점
  5. 부동소수점 오차 해결 방법
  6. BigDecimal을 활용한 고정밀 연산
  7. 실전 예제 코드

 

1. Java의 실수형 데이터 타입 개요

Java에서 실수를 저장하는 기본 데이터 타입은 다음과 같습니다:

  • float: 4바이트 크기 (32비트), 단정밀도
  • double: 8바이트 크기 (64비트), 배정밀도
float f = 3.14f;
double d = 3.14;

 

 

 

2. float vs. double: 차이점 비교

두 데이터 타입의 차이를 비교한 표는 다음과 같습니다.

특성 float double
크기 4바이트 (32비트) 8바이트 (64비트)
정밀도 7자리 15~16자리
사용 예 메모리 절약이 필요한 경우 높은 정밀도가 필요한 경우

 

 

 

3. 실수 연산에서 정밀도 문제

실수형 데이터는 부동소수점 표현 방식을 사용하므로 정확한 값을 저장하지 못하는 경우가 많습니다.

System.out.println(0.1 + 0.2); // 예상: 0.3, 실제: 0.30000000000000004

이 문제는 실수값이 2진수로 정확하게 표현되지 않기 때문에 발생합니다.

 

 

 

4. 실수형 데이터의 연산과 주의점

실수형 데이터의 연산에서는 다음과 같은 주의점이 필요합니다.

  • 비교 연산 시 == 대신 Math.abs(a - b) < epsilon 방식 사용
  • 소수점 연산은 오차가 발생할 수 있음
  • 나눗셈 연산 시 0으로 나누는 상황 방지
if (Math.abs(a - b) < 1e-9) {
    System.out.println("두 수는 같다.");
}

 

 

 

 

5. 부동소수점 오차 해결 방법

부동소수점 오차를 줄이기 위한 방법은 다음과 같습니다.

  1. 정수 연산 활용: 가능한 경우 실수 연산 대신 정수 연산 사용
  2. BigDecimal 사용: 고정밀 계산이 필요한 경우
  3. 비교 연산 시 오차 허용: 절대값 비교 방식

 

 

 

6. BigDecimal을 활용한 고정밀 연산

BigDecimal을 사용하면 높은 정밀도를 유지할 수 있습니다.

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("0.1");
        BigDecimal b = new BigDecimal("0.2");
        System.out.println(a.add(b)); // 정확히 0.3 출력
    }
}

 

 

 

7. 실전 예제 코드

사용자로부터 실수를 입력받고 연산을 수행하는 프로그램을 만들어 보겠습니다.

import java.util.Scanner;

public class FloatingPointExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("첫 번째 실수 입력: ");
        double num1 = scanner.nextDouble();
        
        System.out.print("두 번째 실수 입력: ");
        double num2 = scanner.nextDouble();

        System.out.println("두 수의 합: " + (num1 + num2));
        scanner.close();
    }
}