728x90

컴퓨터 프로그래밍에서 실수 연산은 흔히 오차 문제를 동반합니다.

 

특히 금융, 과학 계산, 그리고 데이터 분석 등 정확한 수치가 중요한 분야에서는 이 문제가 더욱 부각되는 문제인데요.

이번 글에서는 Double의 한계, Float를 사용한 실수 연산의 특징, 그리고 BigDecimal을 활용한 오차 없는 실수 연산 방법을 살펴보겠습니다.


1. Double의 문제: 부동소수점 연산의 한계

Double은 대부분의 프로그래밍 언어에서 기본 실수형으로 사용됩니다.

 

이는 64비트 IEEE 754 표준을 따르며, 빠른 연산 속도와 넓은 범위의 숫자를 처리할 수 있는 장점이 있습니다.

하지만 정확도 면에서는 한계가 있습니다.

public class DoubleExample {
    public static void main(String[] args) {
        double a = 0.1;
        double b = 0.2;
        double c = a + b;

        System.out.println("0.1 + 0.2 = " + c);
    }
}

출력 결과.

0.1 + 0.2 = 0.30000000000000004

왜 이런 일이 발생할까요?

  • Double은 2진수 기반의 부동소수점 표현 방식을 사용합니다.
  • 10진수 0.1과 0.2를 정확히 표현할 수 없기 때문에, 이진수로 변환될 때 근삿값으로 저장됩니다.
  • 이로 인해 연산 결과에도 미세한 오차가 발생합니다.

2. Float 사용: 더 작은 범위, 더 큰 오차

Float는 Double보다 작은 32비트 부동소수점 자료형입니다.

메모리 사용량이 적고 연산 속도가 빠르지만, 표현할 수 있는 유효 숫자 범위가 좁습니다.

public class FloatExample {
    public static void main(String[] args) {
        float a = 0.1f;
        float b = 0.2f;
        float c = a + b;

        System.out.println("0.1f + 0.2f = " + c);
    }
}

출력 결과.

0.1f + 0.2f = 0.3

겉보기에는 정확해 보이지만, 실제로는 내부에서 근삿값을 저장하고 있어 더 작은 숫자 범위에서 더 큰 오차가 발생할 가능성이 높습니다.

Float의 주요 특징

  • 적합한 경우: 높은 정밀도가 요구되지 않는 경우 (예: 게임 개발, 그래픽 연산).
  • 부적합한 경우: 금융 계산이나 통계 연산 등 오차가 치명적인 경우.

3. BigDecimal 사용: 실수 연산의 정밀도 보장

BigDecimal은 Java에서 제공하는 클래스 중 하나로, 정확한 실수 연산을 보장하기 위해 사용됩니다.

이 클래스는 실수를 10진법 기반으로 처리하므로, 부동소수점의 근삿값 문제를 해결할 수 있습니다.

import java.math.BigDecimal;

public class BigDecimalExample {
    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("0.1");
        BigDecimal b = new BigDecimal("0.2");
        BigDecimal c = a.add(b);

        System.out.println("0.1 + 0.2 = " + c);
    }
}

출력 결과.

0.1 + 0.2 = 0.3

중요 사항

  • new BigDecimal(double)로 생성할 경우 부동 소수점의 오차가 그대로 발생할 위험성이 존재합니다.
  • "scale()"메서드로 소수 자릿수를 설정하여 계산 결과를 정리할 수 있습니다.

그럼 뭘 사용해야 할까?

실수 연산은 문제 되는 상황을 인지하고 있지 않다면 쉽게 간과할 수 있는 중요한 이슈입니다.

 

특히 환율, 이율 등과 같이 금전적인 부분이 연결되어 있다면 이는 서비스의 신뢰도를 낮추게 되는 매우 크리티컬 한 문제가 될 수 있습니다.

 

그렇기 때문에 위에 주어진 Double, Float, BigDecimal들을 잘 활용하여 적재적소에 사용해야 하는 것은 중요한 기본이라 생각합니다.

728x90

'Java' 카테고리의 다른 글

[ThreadLocal] Thread영역에 데이터를 저장하고 싶어요  (1) 2025.01.27
[Java] Static  (3) 2024.12.26
[ Basic ] I/O Stream이란?  (0) 2024.12.23
[JPA] 비관적 락 낙관적 락  (0) 2024.06.29
JPA는 어떤 기술일까?  (0) 2024.04.12

+ Recent posts