04 오차해석 - 진법, 수의 표시법, 오차

진법

수의 표기법

수를 나타내는 방법에는 명수법과 기수법이 있다. 명수법은 하나, 둘, 셋… 과 같이 수를 말로 나타내는 것이고, 기수법은 1, 2, 3, … 과 같이 수를 기호로 나타내는 것이다.

기수법

기수법에는 10진법을 비롯하여 2진법, 5진법, 12진법, 60진법 등이 있다. 오늘날 일반적으로 사용하고 있는 진법은 10개의 숫자를 사용하는 10진법 이다.

[십진 정수 예]
\[\begin{align*} 3246_{10} &= 3 \cdot 1000 + 2 \cdot 100 + 4 \cdot 10 + 6 \cdot 1 \\ &= 3 \cdot 10^3 + 2 \cdot 10^2 + 4 \cdot 10^1 + 6 \cdot 10^0 \\ \end{align*}\]

2진법, 8진법, 16진법, …, 다음과 같이 표현된다.
\[\begin{align*} (a_n a_{n_1} \cdots a_1 a_0)_b = a_n \cdot 10^n + a_{n1} \cdot 10^{n1} + \cdots + a1 \cdot 10^{1} + a_0 \cdot 10^0 \\ \end{align*}\]

  • 2진법: 2진법은 두 개의 숫자 0과 1을 사용하여 수를 나타내는 방법으로 컴퓨터 등에 사용하는 중요한 기수법이다. 동양의 ‘음(-)과 양(+)’ 사상에서도 그 기원을 찾을 수 있다.

  • 5진법: 5진법은 다섯 개의 숫자 0,1,2,3,4를 사용하여 수를 나타내는 방법으로, 13세기 말 경까지 유럽에서 사용되었던 로마 숫자가 그 예다.

  • 10진법: 10진법은 0~9까지 10개를 사용하여 수를 나타내는 방법으로, 사람의 손가락이 열 개인 이유에서 비롯되었다. 현재 일상생활을 비롯한 수학의 계산에서 널리 사용되는 가장 보편적인 기수법 이다.

  • 12진법: 12진법은 0~11까지 12개를 사용하여 수를 나타내는 방법으로, 로마 시대에서 사용되었는데 10보다는 12가 약수를 더 많이 가지고 있다는 이유에서 생겼다. 일상 생활에서 12진법을 사용하는 예로 1다스(12개), 1피트(12인치), 1년(12달)이 있다.

  • 16진법: 16진법은 0~9까지의 10개의 숫자와 A,B,C,D,E,F의 6개의 알파벳을 사용하는 방법으로, A가 10~F가 15을 뜻한다. 컴퓨터에서 2진수를 대신해 많이 쓰이고 있다.

  • 60진법: 고대 바빌로니아 시대에서 사용한 기수법으로, 60의 약수가 10보다 월등히 많다는 장점으로 사용되었다. 현재에도 1시간(60분), 1분(60초)의 시간의 단위와 각도의 단위에서 사용되고 있다.

2진 정수와 10진 정수

2진 정수는 다음과 가이 \(0\) 과 \(1\)이 유한수열 형태로 표현된다.

\[(a_n a_{n_1} \cdots a_1 a_0)_2\]

이것을 아래와 같이 계산하면 10진 정수로 변환된다.

\[D = a_n \cdot 2^n + a_{n1} \cdot 2^{n1} + \cdots + a1 \cdot 2^{1} + a_0 \cdot 2^0\]

예제 1. 10진정수 11을 2진정수로 변환하여라.

예제 2. 2진정수 \((10001)_2\)를 10진 정수로 나타내어라.

10진 정수를 2진 정수로 변환하려면, 십진 정수 \(D\)를 \(2\)로 나누어 몫을 \(D1\)이라하면 나머지를 \(a_0\)이다. 이를 반복하여 \(D_1\)을 2로 나누어 몫을 \(D_2\)라고 하면 나머지는 \(a_1\)이다. 이러한 과정을 몫이 \(0\)이 될 때까지 반복한다. 매번 나오는 \(0\)과 \(1\)을 역순으로 나열하면 2진 정수값을 얻을수 있다.

MATLAB에서 2진 정수와 10진 정수 상호 변환 하는 방법을 알아보겠다. MATLAB 에서는 2진정수를 십진정수로 전환하기 위해서 bin2dec 명령을 사용한다. bin2dec은 이진수 문자열을 해당하는 십진수로 반환한다. 이진수 문자열은 \(2^{52}\)보다 작거나 같은 음이 아닌 정수 값을 나타내야 한다. 또한 bin2dec는 입력 문자열에 있는 공백(' ') 문자를 모두 무시한다.

예제 3. 이진수 \(10111\)을 십진수로 변환하여라.

>> bin2dec('10111')    % 2진 정수는 작은따옴표로 묶어야한다.
ans =
    23
 
>> bin2dec(' 10   111 ')   % 공백 문자가 무시되므로 다음 문자열도 결과가 같다.
ans =
    23

MATLAB에서 십진정수를 이진정수로 변환하는 명령어로 dec2bin를 사용한다. 여기서 이진정수는 음이 아닌 정수여야 합니다. 이진정수가 \(2^{52}\)보다 큰 경우, dec2bin이 이진정수의 정확한 표현을 반환하지 못할 수 있다.

예제 4. 십진수 23을 이진수 10111로 변환합니다.

>> dec2bin(23)
ans =
    10111
2진 소수와 10진 소수

2진 소수는 다음과 같이 \(0\)과 \(1\)이 무한수열 형태로 표현된다.

\[B = (.b_1 b_2 \cdots b_n \cdots)_2\]

10진 소수로 변환시키기 위해 다음과 같이 계산한다.

\[D = b_1 2^{-1} + b_2 2^{-2} + b_3 2^{-3} + \cdots\]

예제 5. 2진 소수 \((.111)_2\)를 10진 소수로 변환하여라.

10진 소수를 2진 소수로 변환하기 위해서 식을 다시 써보자.

\[D = b_1 2^{-1} + b_2 2^{-2} + b_3 2^{-3} + \cdots\]

여기에 \(2\)를 곱하면 \(b_1\)은 정수 부분이 된다. 나머지 부분을 \(D_2\)라 한다.

\[D_2 = b_2 2^{-1} + b_3 2^{-2} + b_4 2^{-3} + \cdots\]

\(D_2\)에 다시 \(2\)를 곱하면 \(b_2\)가 정수 부분이 된다. 이과정을 소수 자리가 \(0\)이 될 때까지 계속 진행한다. 이과정에서 생성되는 정수 부분을 차례대로 나열하면 2진 소수값을 얻을 수 있다.

예제 6. 십진 소수 \(0.2\)를 2진 소수로 변환하여라.

MATLAB을 이용하여 2진 소수를 10진 소수로 변환하거나 10진 소수를 2진 소수로 변환하는 경우 Fr_dec2binFr_bin2dec 함수를 사용한다. 이 함수 파일은 MathWorks 홈페이지에서 받을수 있다.

예제 7. MATLAB을 이용하여 2진 소수 \((.010101010101010)_2\)을 10진 소수로 변환하여라. 그리고 10진 소수 \((0.2)_{10}\)을 2진 소수로 변환하라.

수의 표시법

컴퓨터의 기억장치나 연산장치는 양(+), 음(-)(또는 0과 1)만을 구별할 수 있는 비트들로 구성되어 있다. 따라서 컴퓨터에서는 우리가 사용하는 10진법보다 2진법을 많이 사용한다. 컴퓨터에서 수를 표현할 때는 고정소수점 표시법이나 부동소수점 표시법을 사용한다. 정수에서는 주로 고정소수점, 실수에서는 주로 부동소수점 표시법을 사용한다.

고정소수점 표시

소수점을 항상 일정한 위치에 놓는 표시법으로, 일반적으로는 소수점의 위치를 그 수의 제일 오른쪽에 있다고 가정하여 정수계산에서만 사용한다. 실수계산에서도 사용할 수 있으나 프로그램할 때 소수점 위치에 상당히 신경써야 하므로 잘 사용하지 않는다. 2바이트와 4바이트 고정 소수점 형식이 자주 사용되며, 각각 1bit 부호부와 정수부로 표현된다.

부동소수점 표시

소수점의 위치를 일정하게 하지 않고 따로 지시해주는 표시법 이다. 유효숫자를 나타내는 가수부와 소수점의 위치를 나타내는 지수부로 나누어 표현되며, 매우 큰 수와 작은 수 등 넓은 범위의 수를 나타낼 수 있는 것이 특징이다. 실수 계산 에서는 주로 이 방법을 사용하며, 32비트를 한 단어로 사용하는 컴퓨터의 경우에는 0비트는 부호, 1~7비트는 지수, 8~31비트는 가수 부분을 나타낸다. 일반적인 표현식은 다음과 같다.

\[\sigma \cdot \bar{x} \cdot 10^e = \pm (d_0 . d_1 d_2 \dots d_{p-1}) \times \beta ^e\]

여기서 \(\sigma\)는 \(+1\)혹은 \(-1\) 값을 나타내며, 양과 음을 의미한다. \(e\)는 정수로서 \(-99 \leq e \leq 99\) 범위로 소수점의 위치를 나타내는 지수이다. \(1 \leq \bar{x} \leq 10\) 범위의 \(\bar{x}\)는 유효숫자 자릿수를 표시 하는데 이를 가수(mantissa)라고 한다. 가수는 부동소수의 정밀도를 나타낸다.

예를 들어 분수 \(\dfrac{40}{3}\)을 나타내면,

\[\dfrac{40}{3} = +1 \cdot (1.33333\cdots)_{10} \cdot 10^1\]

이다.

2진 부동 소수점 수 \(0.1\) 을 나타내면

\[(0.1)_{10} = (.0001100110011\cdots)_2 = (1.10011001100 \cdots )_2 \cdot 2^{-4}\]
이다.

2진 부동 소수점 수가 32비트 컴퓨터에 저장되는 일반적인 형식은

\[FL(x) = \sigma \cdot ( 1.b_1 b_2 b_3 \cdots b_{23} )_2 \cdot 2^e\]
이다.

여기서 FL(x)는 2진 부동 소수점 수 \(x\) 를 컴퓨터 내부에서 기계 숫자로 변형 시켜 처리한 부동 소수점의 근사값을 나타낸다.

끝수처리

10진수 유효숫자가 \(n\) 자리인 부동소수점 수 \(x\)는

\[\sigma \cdot (d_1 . d_2 d_3 \cdots d_{n})_{10} \times 10 ^e\]

으로 표현 된다.

10진 부동 소수점 수의 일반적인 형태는

\[\sigma \cdot (d_1 . d_2 d_3 \cdots d_{n}d_{n+1} \cdots )_{10} \times 10 ^e\]

이다. 컴퓨터의 성능과 구조에 따라 맞춰 변환된다. 이러한 맞춤 과정은 올림 끝수처리와 내림 끝수처리 혹은 잘라버리기 방법을 이용한다.

잘라버리기 적용하여 \(n\) 자리까지 나타내면 \(n+1\) 자리인 \(d_{n+1}\) 부터 오른쪽 자리를 버린다. 그러므로 잘라버리기 시행한 뒤 10진 부동 소수점 수 \(x\) 가 컴퓨터에 저장되는 형식은

\[\sigma \cdot (d_1 . d_2 d_3 \cdots d_{n})_{10} \times 10 ^e\]

이다. 끝수처리를 적용하여 \(n\) 자리까지 나타내면, \(d_{n+1}\) 의 값이 \(5\) 와 \(9\) 사이의 진수이면 \(d_n\) 에 \(1\) 을 더하고 \(d_{n+1}\) 부터 오른쪽 자리를 버린다. 이것을 10진수 올림 끝수 처리하고 한다. \(d_{n+1}\) 의 값이 \(0\) 과 \(4\) 사이의 진수이면 \(d_n\) 그대로 두고 \(d_{n+1}\) 부터 오른쪽 자리를 버린다. 이것을 10진수 내림 끝수 처리하고 한다.

정규형태

컴퓨터에서 실수를 기억시킬 때는 가수부의 제일 높은 자리에 0 이외의 유효숫자가 올 때까지 지수값을 변환시켜 기억한다. 이렇게 표시된 수를 정규형태라 한다. 컴퓨터에서는 모든 숫자를 반드시 정규형태로 변화시켜 처리하며, 모든 실수는 7비트와 8비트 사이에 소수점이 있는 것으로 간주하여 지수값을 변환시켜 기억한다.

단정도 표현

32비트를 한 단어로 사용하며 가수부에 7자리 정도의 10진수를 기억시킨다.

배정도 표현

64비트를 한 단어로 사용하며 가수부에 16자리 정도의 10진수를 기억시킨다.

오차

실제값은 \(x\) 컴퓨터에 저장된 근사값은 \(\hat{x}\) 라고 하자. 실제값과 근사값의 차이를 오차라고 한다. 오차를 식으로 표현하면 \(x - \hat{x}\) 이다.

오차 발생하는 근본적인 원인은, 수학적으로 모델링하여 계산하는 과정에서 오류가 발생하기 때문이다. 만약 수학적 모델에 오류가 있다면 오차를 줄이기는 힘들다.

컴퓨터가 개발되기 이전 오차는 대부분 연산 오류 때문이었다. 컴퓨터를 사용하면서 프로그래밍 오류가 많아 졌다. 최근 프로그래밍 코드는 더욱 복잡하고 광범위하게 응용되기 때문에 오류를 찾아내고 수정하기 힘들다.

절대오차와 상대오차

실제값과 근삿값 차이의 절댓값을 절대 오차라고 하고

\[| x - \hat{x} |\]

으로 쓸 수 있다.

계산된 오차를 실제값으로 나눈뒤 절댓값을 적용한 것을 상대 오차라고 한다.

\[\left|\frac{x-\hat{x}}{x}\right|\]

예제 8. 유효숫자 여섯 자리와 끝수처리 기능의 컴퓨터가 있다. 부동 소수점 수 \(2.99792458 \times 10^{10}\) 와 \(1.67492716 \times 10^{-24}\) 의 근사값, 절대오차 그리고 상대 오차를 구하여라.

예제 9. 5bit 정밀도와 끝수 처리 기능이 있는 컴퓨터가 있다. 2진 부동 소수점 수 \(x=(1011001.101)_2\) 와 \(y=(.101100110...)_2\) 의 근사값을 구하여라.

유효숫자에 따른 오차

일반적으로 유효숫자는 \(0\) 이 아닌 숫자이다. 컴퓨터를 이용할 때 유효숫자에 따라 오차가 크게 발생할 수 있다.

입력변수 \(x\) 에 대해 함수 \(f(x)\)를

\[f(x) = x[\sqrt{x+1} - \sqrt{x}]\]

라 하자. 변수 \(x\) 의 값을 \(1, 10, 1000, 10000, 100000\) 차례로 입력한다.(여기서 컴퓨터는 6자리 10진수만 표현할 수 있다.)

함수 \(f(x)\) 를 구하는 연산 과정은 다음과 같다.

(1) \(x\) 에 \(1\)을 더하고 제곱근을 구한다.
(2) \(x\) 에 대한 제곱근을 구한다.
(3) (1)과 (2)의 제곱근을 뺀다.
(4) (3)에 \(x\) 의 값을 곱한다.

실제 함수값을 계산하기 위해서는 계산하는 과정마다 끝수처리를 적용하지 않고, 모든 과정이 끝난 이후 끝수처리 한다. 여섯자릿수 맞추면 \(f(1) = 0.414214\) 이다. 반면에 근사값을 계산하기 위해서는 과정마다 끝수처리를 적용하여 계산하면 \(f(1) = 0.414210\) 이다. 같은 방법으로 모두 계산해보면 아래와 같은 표를 얻는다.

\(x\)근사값 \(f(x)\)실제값 \(f(x)\)
\(1\)\(0.414210\)\(0.414214\)
\(10\)\(1.54340\)\(1.54347\)
\(100\)\(4.99000\)\(4.98756\)
\(1000\)\(15.8000\)\(15.8074\)
\(10000\)\(50.0000\)\(49.9988\)
\(100000\)\(100.000\)\(158.113\)

입력값이 증가할 수록 근사값과 실제값 사이에 오차가 커지는것을 볼 수 있다.

예제 9. 방정식 \(a x^2 + b x + c\) 의 근을 구하기 위해 보편적으로 사용하는 공식은 다음과 같다.

\[x = \dfrac{-b \pm \sqrt{b^2-4ac}}{2 a}\]

분모와 분자에 \(-b \mp \sqrt{b^2-4ac}\) 를 곱하면

\[x = \dfrac{-2 c}{b \pm \sqrt{b^2-4ac}}\]

를 얻는다. 3자리 유효숫자로 끝수처리 시행하여 위 식을 각각 사용하여 이차방정식 \(x^2 - 15x + 1 = 0\) 의 근을 계산하여라.

전환오차

컴퓨터에서 프로그래밍 할 때, 실수를 입력한 다음 그 결과를 출력 했을 때, 값이 바뀌는 경우가 있다. 예를 들어 단정도 표현에서 0.23456789는 0.2345679로 출력된다. 다음의 예를 통해 컴퓨터에 \((387.620000)_{10}\) 실수가 입력되고 출력되는 과정을 살펴보면 다음과 같다.

  • 컴퓨터는 우선 \(387.62\)를 16진수로 바꾼다. \((387.620000)_{10} = (183.9EB851EB851⋅⋅⋅)_{16}\)

  • 정규형태로 변경한다. \((0.1839EB851EB851⋅⋅⋅)\times 16^3\)

  • 컴퓨터가 여섯자리 가수부분만 취하는 16진법 컴퓨터라고 가정하면 여섯자리 미만은 버리게 됨 \((0.1839EB) \times 16^3\)

  • 출력하기 위해 10진수로 바꾼다. \((183.9EB)_{16} = (387.6198730)_{10}\)

  • 이 과정에서 오차 \(387.620000-387.61987=0.00013\)이 발생

  • 이처럼 입출력 과정에서 생기는 오차를 전환 오차라고 한다.

반응형