개념 - 실수 자료형의 계산 오차

yunzivv·2025년 3월 7일

JAVA 기초

목록 보기
7/23

실수 자료형의 계산


java에서 실수를 표현하는 자료형은 floatdouble이 있다.
이 자료형들은 계산식에 활용하면 원하는 답을 얻지 못할 수 있다.

1. 실수 계산의 오차

  • 예시 코드
float a = 3.3f;
if (a * 3 == 9.9){
	System.out.println("T");
} else{
	System.out.println("F");
}
출력
F

3.3 * 3을 계산해보면 9.9가 맞으니 T가 출력될 것이라고 생각했다. 하지만 실제 프로그램을 돌려보면 예상한 출력T와 달리 F가 출력된다. 왜 이런 결과가 나올까?
컴퓨터는 사용자가 입력한 10진수를 2진수으로 변환한 후, 부동소수점방식을 사용하여 근사값을 저장하기 때문이다.

이를 이해하기 위해 2진수와 실수표현 방식에 대해 알아야 한다.

2. 2진수


우리가 평범하게 사용하는 수는 0부터 9까지 10가지의 수를 사용하는 10진법이다. 그렇다면 2진법은 2가지의 수를 사용할 것이라고 예상할 수 있다. 2진법은 01 2가지의 수만 사용해서 나타내는 방법이다.

0과 1은 각각 아래와 같은 의미를 가진다.

01
offon
falsetrue

컴퓨터는 이렇게 전기신호 ON(1)과 OFF(0) 두 가지만 받아들일 수 있기 때문에 2진법으로 동작된다.
2진법은 0과 1 두가지의 수로만 구성되어 있어 개념적으로 단순하다. 하지만, 표현할 때 10진수보다 길이가 길어지기 때문에 동시에 복잡하기도 하다. 예시로 10진수 8는 한자리 수로 표현되지만 2진법에서는 1000(2) 4자리의 수로 표현된다. 10진수와 2진수를 서로 변환하는 법은 아래와 같다.

10진법 숫자를 2진법으로 변환하는 법

21 / 2 = 10 ··· 1
10 / 2 = 5 ··· 0
5 / 2 = 2 ··· 1
2 / 2 = 1 ··· 0
1 / 2 = 0 ··· 1

변환하려는 10진수를 더 이상 나누어 떨어지지 않을 때까지 2로 나누고, 그 나머지를 위에서 아래로 읽는다.
위와 같이 10진수 21을 2진수로 변환하면 10101(2)이 된다.

2진법 숫자를 10진법으로 변환하는 법

반대로 2진수를 10진수로 변환할 때는 각 자리의 숫자 * 2의 거듭제곱의 총합으로 계산하면 된다.

위 그림을 해석하면 1*16 + 1*0 + 1*4 + 1*0 + 1*1으로 계산하여 21이라는 결과를 얻을 수 있다.

이제 2진수 개념을 이해했으니, 실수가 어떻게 표현되는 지 알아보자.

정리하다보니 내용이 길어졌다.. 2진수는 컴퓨터, 그리고 지금 배우는 저급언어에서도 매우 다양하게 활용되니 익숙해지는 것이 좋을 것 같다.

3. 실수의 표현방식


java에서 실수를 표현할 때는 floatdouble 자료형을 사용하며 두 자료형은 범위의 차이를 가진다. float은 4byte, double은 8byte의 크기를 가지고 있다. 실수의 표현방식 설명은 float의 크기인 4byte 즉 32비트로 설명한다.

컴퓨터에서 실수를 표현하는 방식은 고정소수점부동소수점 2가지 방식이 있다.

1) 고정소수점

소수점의 위치를 고정시켜 놓고 표현하는 방식이다.

예제 : 5.625를 고정소수점 방식으로 표현

  1. 5.625라는 숫자는 5.623 = 4 + 1 + 0.5 + 0.125 = 2^2 + 2^1 + 2^(-1) + 2^(-1) + 2(-3) = 101.101(2진수)로 표현할 수 있다.
  2. 고정소수점 방식으로 저장하면 각각 부호부에 0(양수), 정수부에 101, 소수부에 101으로 저장된다.

장점 : 계산의 정확도가 높고 계산이 빠르다.
단점 : 정수부분과 소수부분의 자릿수가 작아서 표현할 수 있는 범위가 작다.
(0.12 라는 실수가 존재할 때 소수부분을 표현하기 위해 16비트가 모두 사용된다.)

고정소수점은 표현 범위가 작다는 단점 때문에 java는 부동소수점 방식을 사용한다.

2) 부동소수점


부동소수점이라는 단어를 처음 들었을 때 움직이지 않는 소수점이라고 생각했다. 하지만 부동은 움직이지 아니한다는 뜻(不動)이 아니라 떠서 움직인다(浮動)는 뜻이다.

  • 소수점의 위치를 고정하지 않고 소수점의 위치를 움직이며 더 넓은 범위를 표현한다.
  • 실수를 컴퓨터상에서 근사하여 표현한다.
  • 유효숫자를 나타내는 가수와 소수점의 위치를 풀이하는 지수로 나누어 표현한다.

예제 : 5.625를 부동소수점 방식으로 표현

  1. 5.625라는 숫자는 5.625 = 4 + 1 + 0.5 + 0.125 = 2^2 + 2^1 + 2^(-1) + 2^(-1) + 2(-3) = 101.101(2진수)로 표현할 수 있다.

  2. 소수점을 왼쪽으로 이동시켜 왼쪽에는 한자리만 남게 만든다. 1.01101*(2^2)101.101과 같다. 이것이 정규화된 부동소수점 수이다.

  3. 지수부는 2와(소수점을 앞으로 옮긴 자릿수) Bias인 127을 더하면 129가 된다. (기준값인 127부터 +2만큼 떨어진 값 = 129)

  4. 129를 2진법으로 표현하면 10000001가 된다.

  5. 가수부는 1.01101의 소수점 오른쪽 부분(소수부분)과 나머지는 0으로 채운다.

장점 : 고정소수점 방식보다 넓은 범위의 수를 표현할 수 있다.
단점 : 실수를 정확하게 표현하지 못하고 근사값을 저장한다. (0.3은 2진법으로 무한히 반복되는 값이므로 정확한 계산이 되지 않는다.)

정리하면서 많은 자료를 참고했지만 가장 이해가 잘됐던 숫자를 입력하면 계산결과를 순서대로 자세히 보여주는 부동소수점 계산기를 찾아서 첨부한다.

참고자료


실수 계산
부동소수점 계산기

0개의 댓글