이 페이지의 최신 내용은 아직 번역되지 않았습니다. 최신 내용은 영문으로 볼 수 있습니다.

부동소수점 숫자(Floating-Point Number)

MATLAB®은 배정밀도 형식 또는 단정밀도 형식으로 부동소수점 숫자를 나타냅니다. 디폴트는 배정밀도이지만, 간단한 변환 함수를 사용하여 어느 숫자든 단정밀도로 만들 수 있습니다.

배정밀도 부동소수점

MATLAB은 배정밀도에 대한 IEEE® 표준 754에 따라 배정밀도(또는 double) 데이터형을 생성합니다. double형으로 저장되는 모든 값에는 64비트가 필요하며, 아래 표에 나와 있는 것과 같이 형식이 지정됩니다.

비트

사용법

63

부호(0 = 양수, 1 = 음수)

62 ~ 52

지수, 1023으로 바이어스됨

51 ~ 0

숫자 1.f의 소수부 f

단정밀도 부동소수점

MATLAB은 단정밀도에 대한 IEEE 표준 754에 따라 단정밀도(또는 single) 데이터형을 생성합니다. single형으로 저장되는 모든 값에는 32비트가 필요하며, 아래의 표와 같이 형식이 지정됩니다.

비트

사용법

31

부호(0 = 양수, 1 = 음수)

30 ~ 23

지수, 127로 바이어스됨

22 ~ 0

숫자 1.f의 소수부 f

MATLAB은 32비트를 사용하여 single형 숫자를 저장하므로, 이 숫자는 64비트를 사용하는 double형 숫자보다 더 적은 메모리를 필요로 합니다. 그러나, single형 숫자는 더 적은 비트를 사용하여 저장되므로 double형 숫자보다 작은 정밀도로 표현됩니다.

부동소수점 데이터 생성하기

약 3.4 x 1038보다 크거나 약 -3.4 x 1038보다 작은 값을 저장하려면 배정밀도를 사용하십시오. 이 두 한도 사이의 숫자에 대해서는 배정밀도 또는 단정밀도를 사용할 수 있지만, 단정밀도가 더 적은 메모리를 필요로 합니다.

배정밀도 데이터 생성

MATLAB의 디폴트 숫자형이 double이므로 간단한 대입문을 사용하여 double형을 생성할 수 있습니다.

x = 25.783;

whos 함수는 x에 방금 저장한 값에 대해 MATLAB이 double형으로 구성된 1x1 배열을 생성했음을 보여줍니다.

whos x
  Name      Size                   Bytes  Class

  x         1x1                        8  double

x가 부동소수점 숫자인지 확인하려면 isfloat을 사용하십시오. 이 함수는 입력값이 부동소수점 숫자인 경우 논리값 1(true)을 반환하고, 그렇지 않은 경우 논리값 0(false)을 반환합니다.

isfloat(x)
ans =

  logical

   1

MATLAB 함수 double을 사용하여 다른 숫자형 데이터, 문자 또는 string형 및 논리형 데이터를 배정밀도로 변환할 수 있습니다. 이 예제에서는 부호 있는 정수를 배정밀도 부동소수점으로 변환합니다.

y = int64(-589324077574);          % Create a 64-bit integer

x = double(y)                      % Convert to double
x =
  -5.8932e+11

단정밀도 데이터 생성

MATLAB에서는 기본적으로 숫자형 데이터를 double형으로 저장하므로 single 변환 함수를 사용하여 단정밀도 숫자를 생성해야 합니다.

x = single(25.783);

whos 함수는 구조체에 변수 x의 특성(Attribute)을 반환합니다. 이 구조체의 bytes 필드는 x가 single형으로 저장된 경우 4바이트만 필요함을 보여줍니다. 이와 비교하여, double형으로 저장하는 데는 8바이트가 필요합니다.

xAttrib = whos('x');
xAttrib.bytes
ans =
     4

single 함수를 사용하여 다른 숫자형 데이터, 문자 또는 string형 및 논리형 데이터를 단정밀도로 변환할 수 있습니다. 이 예제에서는 부호 있는 정수를 단정밀도 부동소수점으로 변환합니다.

y = int64(-589324077574);          % Create a 64-bit integer

x = single(y)                      % Convert to single
x =

  single

 -5.8932e+11

부동소수점 숫자에 대해 산술 연산하기

이 섹션에서는 부동소수점 숫자에 대한 산술 연산에 사용할 수 있는 클래스에 대해 설명합니다.

배정밀도 연산

double형과 다음에 나열된 클래스 간에 기본적인 산술 연산을 수행할 수 있습니다. 하나 이상의 피연산자가 정수(스칼라 또는 배열)인 경우 double형 피연산자는 스칼라여야 합니다. 결과는 아래에 별도로 명시된 경우를 제외하고 double형입니다.

  • single — 결과는 single형입니다.

  • double

  • int* 또는 uint* — 결과는 정수 피연산자와 동일한 데이터형을 가집니다.

  • char

  • logical

이 예제에서는 char형 데이터 및 double형 데이터에 대해 산술 연산을 수행합니다. 결과는 double형입니다.

c = 'uppercase' - 32;

class(c)
ans =
   double

char(c)
ans =
   UPPERCASE

단정밀도 연산

single형과 다음에 나열된 클래스 간에 기본적인 산술 연산을 수행할 수 있습니다. 결과는 항상 single형입니다.

  • single

  • double

  • char

  • logical

이 예제에서, 7.5는 기본적으로 double형으로 설정되며, 결과는 single형입니다.

x = single([1.32 3.47 5.28]) .* 7.5;

class(x)
ans =
   single

부동소수점 클래스에 대한 최댓값과 최솟값

double형 클래스와 single형 클래스의 경우 해당 형식으로 나타낼 수 있는 최대 숫자와 최소 숫자가 있습니다.

최대 및 최소 배정밀도 값

MATLAB 함수 realmaxrealmindouble 데이터형으로 나타낼 수 있는 최댓값 및 최솟값을 반환합니다.

str = 'The range for double is:\n\t%g to %g and\n\t %g to  %g';
sprintf(str, -realmax, -realmin, realmin, realmax)

ans =
The range for double is:
   -1.79769e+308 to -2.22507e-308 and
    2.22507e-308 to  1.79769e+308

realmax보다 크거나 -realmax보다 작은 숫자에는 각각 양수 무한대 및 음수 무한대 값이 대입됩니다.

realmax + .0001e+308
ans =
   Inf

-realmax - .0001e+308
ans =
  -Inf

최대 및 최소 단정밀도 값

MATLAB 함수 realmaxrealmin은 인수 'single'을 사용하여 호출되는 경우 single 데이터형으로 나타낼 수 있는 최댓값과 최솟값을 반환합니다.

str = 'The range for single is:\n\t%g to %g and\n\t %g to  %g';
sprintf(str, -realmax('single'), -realmin('single'), ...
    realmin('single'), realmax('single'))

ans =
The range for single is:
	-3.40282e+38 to -1.17549e-38 and
	 1.17549e-38 to  3.40282e+38

realmax('single')보다 크거나 -realmax('single')보다 작은 숫자에는 각각 양수 무한대 및 음수 무한대 값이 대입됩니다.

realmax('single') + .0001e+038
ans =

  single

   Inf

-realmax('single') - .0001e+038
ans =

  single

  -Inf

부동소수점 데이터의 정확도

부동소수점 산술 계산의 결과가 예상한 만큼 정밀하지 않을 경우 컴퓨터 하드웨어의 한계 때문일 수 있습니다. 하드웨어에 비트가 부족하여 완전히 정확한 결과를 나타낼 수 없고 따라서 결과 값이 잘렸기 때문에 결과의 정확도가 다소 떨어졌을 수 있습니다.

배정밀도 정확도

배정밀도 숫자는 유한하기 때문에 배정밀도 저장 공간에 모든 숫자를 나타낼 수는 없습니다. 어느 컴퓨터에서나 각각의 배정밀도 숫자와 그다음으로 큰 배정밀도 숫자 사이에는 약간의 간격이 있습니다. eps 함수를 사용하여 이러한 간격의 크기를 확인할 수 있으며, 이 간격에 따라 결과의 정밀도가 제한됩니다. 예를 들어, 5와 그다음으로 큰 배정밀도 숫자 사이의 거리를 확인하려면 다음을 입력하십시오.

format long

eps(5)
ans =
     8.881784197001252e-16

그러면 5와 5 + eps(5) 사이에 배정밀도 숫자가 없다는 내용이 표시됩니다. 배정밀도 계산에서 답으로 5를 반환할 경우 결과는 eps(5) 내에서만 정확합니다.

eps(x)의 값은 x에 따라 달라집니다. 이 예제에서는 x가 증가함에 따라 eps(x)도 증가함을 보여줍니다.

eps(50)
ans =
     7.105427357601002e-15

입력 인수 없이 eps를 입력하면 MATLAB은 1과 그다음으로 큰 배정밀도 숫자 사이의 거리인 eps(1)의 값을 반환합니다.

단정밀도 정확도

이와 유사하게, 두 개의 단정밀도 숫자 사이에도 간격이 있습니다. xsingle형인 경우, eps(x)x와 그다음으로 큰 단정밀도 숫자 사이의 거리를 반환합니다. 예를 들어, 다음은

x = single(5);
eps(x)

다음 결과를 반환합니다.

ans =

  single

  4.7684e-07

참고로, 이 결과는 eps(5)보다 큽니다. 배정밀도 숫자보다 단정밀도 숫자가 더 적으므로 단정밀도 숫자 사이의 간격은 배정밀도 숫자 사이의 간격보다 큽니다. 즉, 단정밀도 산술 연산의 결과는 배정밀도 산술 연산의 결과보다 정밀도가 떨어집니다.

double형 숫자 x의 경우, eps(single(x))xdouble형에서 single형으로 변환할 때 반올림되는 숫자의 상한을 제공합니다. 예를 들어, 배정밀도 숫자 3.14single형으로 변환하면 다음에 의해 반올림됩니다.

double(single(3.14) - 3.14)
ans =
   1.0490e-07

3.14가 반올림되는 숫자는 다음보다 작습니다.

eps(single(3.14))
ans =

  single

  2.3842e-07

흔히 발생하는 부동소수점 산술 연산 관련 문제와 방지책

MATLAB의 거의 모든 연산은 IEEE 표준 754에 따라 배정밀도 산술 연산으로 수행됩니다. 컴퓨터는 유한 정밀도로만 숫자를 표현하기 때문에(배정밀도에는 52 가수 비트가 필요), 경우에 따라 수학적으로 직관적이지 않은 계산 결과가 생성될 수 있습니다. 이러한 결과는 MATLAB의 버그가 아니라는 점을 유의해야 합니다.

이러한 경우를 식별하는 데 도움이 되도록 다음 예제를 참고하십시오.

예제 1 — 반올림 또는 결과가 예상과 다른 경우

십진수 4/3는 이진 소수부로 정확히 나타낼 수 없습니다. 이러한 이유로, 다음 계산의 결과는 0이 아니라 수량 eps로 나타납니다.

e = 1 - 3*(4/3 - 1)

e =
   2.2204e-16

이와 유사하게, 0.1은 이진수로 정확히 나타낼 수 없습니다. 따라서, 다음과 같은 직관적이지 않은 동작이 발생합니다.

a = 0.0;
for i = 1:10
  a = a + 0.1;
end
a == 1
ans =

  logical

   0

참고로, 연산 순서에 따라 계산 결과가 달라질 수 있습니다.

b = 1e-16 + 1 - 1e-16;
c = 1e-16 - 1e-16 + 1;
b == c
ans =

  logical

   0

부동소수점 숫자 사이에는 간격이 있습니다. 다음에서 확인할 수 있듯이 숫자가 커질수록 간격도 커집니다.

(2^53 + 1) - 2^53

ans =
     0

pi가 실제로 π가 아니므로 당연히 sin(pi)도 정확히 0이 아닙니다.

sin(pi)

ans =
     1.224646799147353e-16

예제 2 — 재해성 소거(Catastrophic Cancellation)

거의 동일한 피연산자에서 뺄셈이 수행되면 경우에 따라 예기치 않게 소거가 일어날 수 있습니다. 다음은 스왐핑(Swamping - 덧셈이 무의미해지는 정밀도 손실 현상)으로 인해 소거가 일어나는 경우를 보여주는 예제입니다.

sqrt(1e-16 + 1) - 1

ans =
     0

expm1, log1p 등의 일부 MATLAB 함수를 사용하여 재해성 소거(Catastrophic Cancellation)의 영향을 보완할 수 있습니다.

예제 3 — 부동소수점 연산 및 선형 대수

선형 대수 문제를 풀 때 반올림, 소거 및 기타 부동소수점 산술 연산의 특성이 결합할 경우 엉뚱한 계산 결과를 얻게 될 수 있습니다. MATLAB은 다음 행렬 A가 조건이 나쁜 행렬이어서 시스템 Ax = b가 작은 섭동에도 영향을 받을 수 있다는 내용의 경고를 표시합니다.

A = diag([2 eps]); 
b = [2; eps]; 
y = A\b; 
Warning: Matrix is close to singular or badly scaled.
         Results may be inaccurate. RCOND = 1.110223e-16.

이는 IEEE 부동소수점 산술 연산이 MATLAB에서의 계산에 어떻게 영향을 미치는지를 보여주는 몇 가지 예에 불과합니다. 참고로, IEEE 754 산술 연산에서 수행되는 모든 계산이 영향을 받으며, 여기에는 MATLAB은 물론, C 또는 FORTRAN으로 작성된 응용 프로그램도 포함됩니다.

참고 문헌

[1] Moler, Cleve. “Floating Points.” MATLAB News and Notes. Fall, 1996.

[2] Moler, Cleve. Numerical Computing with MATLAB. Natick, MA: The MathWorks, Inc., 2004.