Java

[Java] 자바에서 앱실론(Epsilon)과 부동소수점 오차 검사

yujinius 2024. 5. 30. 19:26

 

부동소수점(Floating-Point) 수는 컴퓨터에서 실수를 표현하는 방식 중 하나입니다. 그러나 부동소수점은 근본적으로 정확하지 않기 때문에 미세한 오차가 발생할 수 있습니다. 이로 인해 두 부동소수점 수를 비교할 때 문제가 발생할 수 있습니다. 이러한 문제를 해결하기 위해 자주 사용되는 개념이 바로 '앱실론(epsilon)'입니다.

 

이러한 앱실론에 대해 알아보도록 하겠습니다. 

앱실론(Epsilon)이란?

앱실론은 두 부동소수점 수를 비교할 때 그 차이가 무시할 수 있을 정도로 작은 값을 의미합니다. 부동소수점 연산의 특성상 완벽하게 같은 값을 얻기 어려우므로, 두 값의 차이가 앱실론보다 작으면 두 값이 같다고 간주합니다.

앱실론이 생기는 원인

앱실론이 필요한 이유는 부동소수점 표현 방식에 기인합니다. 컴퓨터는 실수를 이진수 형태로 저장하는데, 이는 다음과 같은 문제를 초래합니다:

  1. 유한한 비트 수: 컴퓨터는 유한한 비트 수로 실수를 저장합니다. 이로 인해 모든 실수를 정확하게 표현할 수 없습니다. 예를 들어, 0.1과 같은 숫자는 이진수로 무한 소수가 되기 때문에 정확하게 저장할 수 없습니다.
  2. 정밀도의 한계: 부동소수점 연산은 정밀도의 한계로 인해 작은 오차를 발생시킵니다. 연산이 반복될수록 이러한 오차는 누적될 수 있습니다.
  3. 이진수와 십진수의 차이: 일부 십진수는 이진수로 정확히 표현되지 않으므로, 부동소수점 연산 시 예상치 못한 결과가 발생할 수 있습니다.

이러한 이유로 부동소수점 수를 비교할 때는 직접적으로 == 연산자를 사용하지 않고, 앱실론을 사용하여 오차 범위 내에서 비교하는 것이 중요합니다.

Java에서 부동소수점 비교하기

자바에서 앱실론을 사용하여 부동소수점 수를 비교하는 예시를 살펴보겠습니다.

j 
public class EpsilonExample {
    public static void main(String[] args) {
        double a = 0.1 + 0.2;
        double b = 0.3;
        double epsilon = 1e-10; // 10의 -10승, 아주 작은 값

        if (Math.abs(a - b) < epsilon) {
            System.out.println("a와 b는 같은 값으로 간주됩니다.");
        } else {
            System.out.println("a와 b는 다른 값입니다.");
        }
    }
}


예시 설명

  1. double a = 0.1 + 0.2;와 double b = 0.3;에서 a와 b는 동일한 값으로 보일 수 있지만, 실제로는 미세한 차이가 존재합니다.
  2. epsilon은 두 수의 차이가 이 값보다 작을 때 두 수가 동일하다고 간주하는 임계값입니다.
  3. Math.abs(a - b)는 a와 b의 차이의 절대값을 계산합니다.
  4. 만약 이 차이가 epsilon보다 작다면 a와 b는 동일하다고 간주됩니다.

위 코드를 실행하면 a와 b는 실제로는 약간의 차이가 있지만, 이 차이는 epsilon보다 작기 때문에 "a와 b는 같은 값으로 간주됩니다."라는 메시지가 출력됩니다.

 

부동소수점 수를 비교할 때는 직접적으로 == 연산자를 사용하지 말고, epsilon을 사용하여 두 수의 차이가 무시할 수 있을 정도로 작은지를 확인해야 합니다. 이를 통해 부동소수점의 미세한 오차로 인한 비교 오류를 방지할 수 있습니다. Java에서는 Math.abs와 같은 내장 함수를 활용하여 이러한 비교를 쉽게 구현할 수 있습니다.