Main Content

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

“부동소수점”은 실수(분수 및 소수 포함)를 인코딩하는 데이터형 세트를 지칭합니다. 부동소수점 데이터형은 소수점 뒤에 다양한 자릿수를 허용하는 반면, 고정소수점 데이터형은 소수점 앞과 뒤에 특정 자릿수가 고정되어 있습니다. 따라서 부동소수점 데이터형은 고정소수점 데이터형보다 더 넓은 범위의 숫자를 나타낼 수 있습니다.

숫자 표현 및 저장에 사용할 수 있는 메모리가 제한되어 있기 때문에 컴퓨터가 표현할 수 있는 유한 정밀도 부동소수점 숫자들의 개수에는 제한이 있습니다. 이 유한 정밀도로 인해 정확한 값이나 고정밀도가 필요한 부동소수점 계산의 정확도가 제한될 수 있습니다. 일부 숫자가 정확하게 표현되지 않기 때문입니다. 이러한 제한에도 불구하고 부동소수점 숫자는 계산이 빠르고 그 정밀도와 범위가 실제 문제를 해결하기에 충분하기 때문에 널리 사용됩니다.

MATLAB의 부동소수점 숫자

MATLAB®에는 IEEE® 표준 754를 따르는 배정밀도(double) 및 단정밀도(single) 부동소수점 숫자에 대한 데이터형이 있습니다. 기본적으로 MATLAB은 부동소수점 숫자를 배정밀도로 표현합니다. 배정밀도를 사용하면 숫자를 더 높은 정밀도로 나타낼 수 있지만 단정밀도보다 더 많은 메모리가 필요합니다. 메모리를 절약하기 위해 single 함수를 사용하여 숫자를 단정밀도로 변환할 수 있습니다.

배정밀도 또는 단정밀도를 사용하여 약 -3.4 × 1038~3.4 × 1038 사이의 숫자를 저장할 수 있습니다. 이 범위를 벗어나는 숫자가 있으면 배정밀도를 사용하여 저장하십시오.

배정밀도 데이터 생성하기

MATLAB의 디폴트 숫자형이 double형이므로 간단한 대입문을 사용하여 배정밀도 부동소수점 숫자를 생성할 수 있습니다.

x = 10;
c = class(x)
c =
   'double'

double 함수를 사용하여 숫자형 데이터, 문자 또는 string형 및 논리형 데이터를 배정밀도로 변환할 수 있습니다. 예를 들어, 부호 있는 정수를 배정밀도 부동소수점 숫자로 변환해 보겠습니다.

x = int8(-113);
y = double(x)
y =
   -113

단정밀도 데이터 생성하기

단정밀도 숫자를 생성하려면 single 함수를 사용합니다.

x = single(25.783);

single 함수를 사용하여 숫자형 데이터, 문자 또는 string형 및 논리형 데이터를 단정밀도로 변환할 수도 있습니다. 예를 들어, 부호 있는 정수를 단정밀도 부동소수점 숫자로 변환해 보겠습니다.

x = int8(-113);
y = single(x)
y =
   single
   -113

MATLAB이 부동소수점 숫자를 저장하는 방법

MATLAB은 IEEE 형식에 따라 doublesingle 부동소수점 데이터형을 생성하고 기본적으로 가장 가까운 수로 반올림(경계에 놓인 숫자는 가장 가까운 짝수로 반올림)하는 반올림 모드를 따릅니다.

부동소수점 숫자 x의 형식은 다음과 같습니다.

x=1s(1+f)2e

여기서

  • s는 부호를 결정합니다.

  • f는 분수, 즉 가수(mantissa)이며 0 ≤ f < 1을 충족합니다.

  • e는 지수(exponent)입니다.

s, f, e는 각각 메모리의 유한한 비트 수로 결정되며, fe는 데이터형의 정밀도에 따라 달라집니다.

double형 숫자를 저장하려면 다음 표에 나와 있는 것처럼 64비트가 필요합니다.

비트너비사용
631부호를 저장합니다. 0은 양수이고 1은 음수입니다.
62 ~ 52111023만큼 편향된 지수를 저장합니다.
51 ~ 052가수를 저장합니다.

single형 숫자를 저장하려면 다음 표에 나와 있는 것처럼 32비트가 필요합니다.

비트너비사용
311부호를 저장합니다. 0은 양수이고 1은 음수입니다.
30 ~ 238127만큼 편향된 지수를 저장합니다.
22 ~ 023가수를 저장합니다.

부동소수점 데이터형의 최댓값과 최솟값

배정밀도 및 단정밀도 데이터형에는 표현할 수 있는 최댓값과 최솟값이 있습니다. 표현 가능한 범위를 벗어난 숫자에는 양수 무한대 또는 음수 무한대가 대입됩니다. 그러나 표현 가능한 범위 내의 숫자도 정밀도가 보장되는 부동소수점 숫자들 사이의 간격으로 인해 정확하게 저장할 수 없는 경우가 있으며 이러한 숫자에는 반올림 오차가 있을 수 있습니다.

최대 및 최소 배정밀도 값

realmaxrealmin 함수를 각각 사용하여 double 데이터형으로 표현할 수 있는 양의 최댓값과 양의 최솟값을 구합니다.

m = realmax
m =
   1.7977e+308
n = realmin
n =
   2.2251e-308

realmaxrealmin은 정규화된 IEEE 값을 반환합니다. realmaxrealmin-1을 곱하여 음의 최댓값과 음의 최솟값을 구할 수 있습니다. realmax보다 크거나 –realmax보다 작은 숫자에는 각각 양수 무한대 또는 음수 무한대 값이 대입됩니다.

최대 및 최소 단정밀도 값

인수 "single"을 사용해 realmaxrealmin 함수를 호출하여 single 데이터형으로 표현할 수 있는 양의 최댓값과 양의 최솟값을 구합니다.

m = realmax("single")
m =
   single
   3.4028e+38
n = realmin("single")
n =
   single
   1.1755e-38

realmax("single")realmin("single")–1을 곱하여 음의 최댓값과 음의 최솟값을 구할 수 있습니다. realmax("single")보다 크거나 –realmax("single")보다 작은 숫자에는 각각 양수 무한대 또는 음수 무한대 값이 대입됩니다.

정밀도가 보장되는 최대 부동소수점 정수

부동소수점 데이터형을 사용하여 모든 정수를 표현할 수 있는 것은 아닙니다. 정밀도가 보장되는 최대 정수 xx보다 작거나 같으면서 정확하게 표현 가능한 모든 정수들 중에서 가장 큰 정수이지만 x + 1은 부동소수점 형식으로 나타낼 수 없습니다. flintmax 함수는 정밀도가 보장되는 최대 정수를 반환합니다. 예를 들어, flintmax 함수를 사용하여 배정밀도 부동소수점 형식의 정밀도가 보장되는 최대 정수인 253을 구합니다.

x = flintmax
x =
   9.0072e+15

단정밀도 부동소수점 형식의 정밀도가 보장되는 최대 정수인 224을 구합니다.

y = flintmax("single")
y =
   single 
   16777216

정수 데이터형을 부동소수점 데이터형으로 변환하면 부동소수점 형식으로 정확하게 표현할 수 없는 정수의 정확도가 손실됩니다. 부동소수점 숫자인 flintmax는 동일한 비트 수를 사용하여 정수 데이터형으로 표현할 수 있는 가장 큰 정수보다 작습니다. 예를 들어, 배정밀도의 flintmax는 253이고 int64 유형의 최댓값은 264 – 1입니다. 따라서 253보다 큰 정수를 배정밀도로 변환하면 정확도가 손실됩니다.

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

부동소수점 데이터의 정확도는 다음과 같은 몇 가지 요소의 영향을 받을 수 있습니다.

  • 컴퓨터 하드웨어의 한계 — 예를 들어, 메모리가 부족한 하드웨어는 부동소수점 계산의 결과를 자릅니다.

  • 각 부동소수점 숫자와 그다음으로 큰 부동소수점 숫자 사이의 간격 — 이러한 간격은 모든 컴퓨터에 존재하고 정밀도를 제한합니다.

부동소수점 숫자 사이의 간격

eps 함수를 사용하여 정밀도가 보장되는 부동소수점 숫자들 사이의 간격 크기를 확인할 수 있습니다. 예를 들어, 5와 그다음으로 큰 배정밀도 숫자 사이의 거리를 구해 보겠습니다.

e = eps(5)
e =
   8.8818e-16

55 + eps(5) 사이의 숫자는 배정밀도 형식으로 표현할 수 없습니다. 배정밀도 계산에서 답으로 5가 반환될 경우 결과는 eps(5) 이내에서 정확합니다. 이 정확도 반지름을 종종 머신 엡실론이라고 합니다.

부동소수점 숫자 사이의 간격은 균일하지 않습니다. 예를 들어, 1e10과 그다음으로 큰 배정밀도 숫자 사이의 간격은 5와 그다음으로 큰 배정밀도 숫자 사이의 간격보다 큽니다.

e = eps(1e10)
e =
   1.9073e-06

마찬가지로, 5와 그다음으로 큰 단정밀도 숫자 사이의 거리를 구해 보겠습니다.

x = single(5);
e = eps(x)
e = 
   single 
   4.7684e-07

단정밀도 숫자가 더 적으므로 단정밀도 숫자 사이의 간격은 배정밀도 숫자 사이의 간격보다 큽니다. 따라서 단정밀도 계산 결과는 배정밀도 계산 결과보다 정밀도가 떨어집니다.

배정밀도 숫자를 단정밀도 숫자로 변환하는 경우 eps 함수를 사용하여 반올림되는 숫자의 상한을 확인할 수 있습니다. 예를 들어, 배정밀도 숫자 3.14를 단정밀도로 변환하면 이 숫자는 최대 eps(single(3.14))만큼 반올림됩니다.

정밀도가 보장되는 부동소수점 정수 사이의 간격

flintmax 함수는 부동소수점 형식의 정밀도가 보장되는 최대 정수를 반환합니다. 이 값보다 큰 값에 대해서는 정밀도가 보장되는 부동 소수점 정수들 사이의 간격이 1보다 큽니다.

eps를 사용하여 flintmax와 다음 부동소수점 숫자 사이의 간격을 구합니다.

format long
x = flintmax
x =
   9.007199254740992e+15
e = eps(x)
e =
   2

eps(x)2이므로 정확하게 표현할 수 있는 그다음으로 큰 부동소수점 숫자는 x + 2입니다.

y = x + e
y =
   9.007199254740994e+15

x1을 더하면 결과는 x로 반올림됩니다.

z = x + 1
z =
   9.007199254740992e+15

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

부동소수점 숫자를 사용한 산술 연산에서 다양한 데이터형을 사용할 수 있으며 결과의 데이터형은 입력 유형에 따라 달라집니다. 그러나 서로 다른 데이터형으로 연산을 수행하는 경우 근사나 중간 변환으로 인해 일부 계산이 정확하지 않을 수 있습니다.

배정밀도 피연산자

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

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

  • double

  • int8, int16, int32, int64 — 결과는 정수 피연산자와 동일한 데이터형입니다.

  • uint8, uint16, uint32, uint64 — 결과는 정수 피연산자와 동일한 데이터형입니다.

  • char

  • logical

단정밀도 피연산자

single형과 다음에 나열된 데이터형 간에 기본적인 산술 연산을 수행할 수 있습니다. 결과는 single형입니다.

  • single

  • double

  • char

  • logical

부동소수점 산술 연산에서의 예상치 않은 결과

MATLAB의 거의 모든 연산은 IEEE 표준 754에 따라 배정밀도 산술 연산으로 수행됩니다. 컴퓨터는 유한 정밀도로 숫자를 표현하기 때문에, 일부 계산에서 수학적으로 직관적이지 않은 결과가 생성될 수 있습니다. 부동소수점 숫자를 사용하여 계산하는 동안 발생할 수 있는 몇 가지 흔한 문제는 반올림 오차, 소거, 스왐핑 및 중간 변환입니다. 예상치 않은 결과는 MATLAB의 버그가 아니며 부동소수점 숫자를 사용하는 모든 소프트웨어에서 발생합니다. 숫자의 정확한 유리수 표현을 위해서는 Symbolic Math Toolbox™를 사용해 보십시오.

반올림 오차

부동소수점 숫자의 유한 정밀도 표현으로 인해 반올림 오차가 발생할 수 있습니다. 예를 들어, 숫자 4/3는 이진 소수부로 정확히 표현할 수 없습니다. 따라서 이 계산은 0이 아니라 수량 eps(1)을 반환합니다.

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

마찬가지로, pi는 π의 정확한 표현이 아니므로 sin(pi)는 정확히 0이 아닙니다.

x = sin(pi)
x =
   1.2246e-16

반올림 오차는 부동소수점 숫자에서 많은 연산을 수행할 때 가장 두드러지며, 오차가 누적되고 심각해질 수 있습니다. 가능한 경우 항상 연산의 수를 최소화하는 것이 가장 좋습니다.

소거

소거는 eps로 측정한 크기가 거의 동일한 두 숫자 간에 뺄셈을 수행할 때 발생할 수 있습니다. 예를 들어, eps(2^53)2이므로 숫자 2^53 + 12^53은 동일한 부동소수점 표현을 갖습니다.

x = (2^53 + 1) - 2^53
x =
   0

가능한 경우 원래 계산과 동등하되 소거를 피할 수 있는 다른 형식으로 계산을 다시 작성해 보십시오.

스왐핑

스왐핑(Swamping)은 크기 차이가 매우 심한 부동소수점 숫자들을 대상으로 연산을 수행할 때 발생할 수 있습니다. 예를 들어, 다음 계산은 덧셈이 무의미해지는 정밀도 손실 현상을 보여줍니다.

x = 1 + 1e-16
x =  
   1

중간 변환

서로 다른 데이터형에 산술 연산을 수행하면 중간 계산 및 변환에서 예상치 않은 결과가 발생할 수 있습니다. 예를 들어, xy가 둘 다 0.2이더라도 뺄셈을 수행하면 0이 아닌 결과가 산출됩니다. 그 이유는 뺄셈이 수행되기 전에 y가 먼저 double형으로 변환되기 때문입니다. 그런 다음 이 뺄셈 결과는 singlez로 변환됩니다.

format long 
x = 0.2
x = 
   0.200000000000000
y = single(0.2)
y = 
   single
   0.2000000
z = x - y
z = 
   single 
   -2.9802323e-09

선형 대수

위에서 설명한 것과 같은 부동소수점 산술 연산에서 흔히 발생하는 문제는 관련된 계산이 일반적으로 여러 단계로 구성되기 때문에 선형 대수 문제에 적용할 때 심각해질 수 있습니다. 예를 들어, 선형 연립방정식 Ax = b를 풀 때 MATLAB은 피연산자 행렬 A의 조건이 나쁘므로 결과가 부정확할 수 있다는 내용의 경고를 표시합니다.

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

참고 문헌

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

참고 항목

함수