스파이더 웹 개발

부동 소수점 오차 문제점 본문

Java

부동 소수점 오차 문제점

스파이더웹 2022. 7. 20. 13:44
728x90
반응형

실수 표현 방식

컴퓨터는 모든 수를 0과 1로 이루어진 2진수로 표현한다. 이것은 정수뿐만 아니라 소수점이 존재하는 실수에서도 표현된다

실수를 표현하기 위한 방법은 대표적으로 2가지가 있다

  1. 고정 소수점 방식
  2. 부동 소수점 방식

고정 소수점 방식

실수는 보통 정수부와 소수부로 나눌 수 있다. 따라서 실수를 표현하는 가장 간단한 방법은 소수부의 자릿수를 미리 정하고, 고정된 자릿수의 소수를 표현하는 것이다.

32비트 CPU에서 고정 소수점 방식 표현

고정 소수점 방식은 정수부와 소수부의 자릿수가 크지 않아, 표현할 수 있는 범위가 매우 작다는 단점이 있다 

부동 소수점 방식

실수는 보통 정수부와 소수부로 나누지만, 가수부와 지수부로 나누어 표현할 수도 있다.

부동 소수점 방식은 실수를 a*2^b 형식으로 저장한다.

이때 a는 1보다 크거나 같고, 2보다 작은 실수이다.

고정 소수점 방식은 제한된 자릿수로 인해 표현할 수 있는 범위가 매우 작다. 하지만, 부동 소수점 방식은 위의 수식을 이용하여 매우 큰 실수까지도 표현할 수 있다.

현재 대부분의 시스템에서는 부동 소수점 방식으로 실수를 표현할 수 있다.

64비트 CPU의 double형 실수를 IEEE 부동 소수점 방식으로 표현

지수부는 자릿수(크기)를 나타내는 부분이다. 즉 가수의 어디쯤에 소수점이 있는지 나타낸다.

가수부는 실수의 실제 값을 표현하는 부분이다.

부동 소수점 방식 오차

부동 소수점 방식은 고정 소수점 방식보다 많은 범위까지 표현할 수 있지만, 항상 오차가 존재한다는 단점을 가지고 있다.

부동 소수점 방식에서 오차는 위에서 살펴본 공식에 의해 발생한다.

해당 공식을 사용하면 표현할 수 있는 범위는 늘지만, 10진수를 정확하게 표현할 수는 없다.

public class Test {

    public static void main(String[] args) {
        double a = 12.23;
        double b = 34.45;

        System.out.println(a+b);

    }

}
//예상 값으로는 46.68을 예상하겠지만 실제 결과 값은
// 46.68000000000001으로 나오는 것을 확인 할 수 있다

이와 같이 실수 연산에서는 소수점 단위 값을 정확히 표현하는 것이 아니라 근사값으로 처리하기 때문에 오차가 발생할 수 있다.

해결방법

이러한 부동 소수점 표현 방식의 오차를 해결하기 위해 자바에서는 BigDecimal 클래스를 제공하고 있다. 소수점을 다루는 연산을 한다면 BigDecimal클래스의 사용은 필수적이다.

주의할점 

BigDecimal 클래스는 java.math 패키지 안에 포함되어 있다. 보통 생성자와 파라미터로 문자열을 넘겨 생성하는 것이 기본적이지만, 정적 팩토리 메서드도 제공한다. 생성자를 사용할 때 주의할 점은, 문자열이 아닌 double 타입 값을 넘기면 안 된다.

728x90
반응형

'Java' 카테고리의 다른 글

Parameter와 Arguement의 차이  (1) 2022.07.20
클래스 변수, 인스턴스 변수, 지역 변수  (0) 2022.07.20
런타임 vs 컴파일 타임  (0) 2022.07.20
메서드와 함수의 차이  (0) 2022.07.20
자바 final 키워드  (0) 2022.07.20
Comments