# 근사해의 정밀도와 정확도

#### 오차 측정의 개념

수치해석에서 어떤 문제를 풀 때, 해석적(이론적)으로 구해진 참값을 정확히 구하기가 불가능하거나 매우 어려운 경우가 많다. 그 결과로서 우리가 실제로 얻는 해는 참값에 대한 **근사해**가 된다. 이때, 근사해와 참값 사이의 오차를 측정하는 방법을 적절히 설정하고 분석하는 것은 중요한 문제이다. 오차를 어떻게 측정하고, 그 오차가 문제 풀이 과정 전반에서 어떠한 의미를 가지는지 파악함으로써, 계산 결과가 얼마나 믿을 만한지, 그리고 계산 과정에서 발생할 수 있는 잠재적 불안정성이나 왜곡의 요인을 어떻게 해석해야 하는지를 알 수 있다.

#### 근사해의 정확도(Accuracy)

어떤 양의 **참값**을 $x$라 하고, 그에 대한 **근사값**을 $\hat{x}$라 할 때, 가장 기본적인 오차는

$$
x - \hat{x}
$$

로 정의된다. 이 값이 얼마나 작은지를 통해 근사해가 참값에 얼마나 가까운가(즉, 얼마나 정확한가)를 가늠한다. 이를 **절대 오차**라고 부르며, 다음과 같이 표현된다.

$$
\text{절대 오차} = |x - \hat{x}|
$$

그런데 실제 수치 계산에서는 참값의 규모가 서로 다를 수 있으므로, 단순 절대 오차만으로는 두 값 사이의 ‘비교적 크기 차이’를 평가하기 어려운 경우가 많다. 예를 들어, $x$의 규모가 매우 큰 경우에 일정량의 오차가 있더라도 이는 상대적으로 작게 보일 수 있고, 반대로 $x$의 규모가 아주 작은 경우에는 같은 양의 절대 오차도 매우 크게 보일 수 있다. 이런 맥락에서 **상대 오차**는

$$
\text{상대 오차} = \frac{|x - \hat{x}|}{|x|}
$$

로 정의된다. 즉, 참값의 크기에 대비하여 근사값이 어느 정도로 오차를 가지는지를 평가할 수 있도록 한다.

하지만 많은 상황에서 참값 $x$를 정확히 모르는 경우가 대부분이므로, 실제 계산에서는 참값 $x$ 대신 근사값 $\hat{x}$를 기준으로 오차를 재정의하거나, 혹은 다른 예측값이나 사전에 알려진 추정치를 사용하기도 한다. 예를 들어, 알고리즘의 수렴 과정을 모니터링하기 위해 연속된 두 근사해 $\hat{x}*{k}$, $\hat{x}*{k+1}$ 간의 차이를 상대값으로 평가하기도 한다. 이는 수치해석에서 알고리즘을 중단(termination)시키거나, 혹은 수렴 여부를 판단하기 위한 실용적인 방법이 되기도 한다.

정확도(accuracy)는 결국 참값과의 일치 정도를 나타내는 지표이므로, 가능한 한 정확도가 높은 해를 찾기 위해서는 문제 설정 자체의 오류(모델링 오차)와 계산 과정에서 발생하는 여러 종류의 수치 오차(반올림 오차, 절단 오차 등)를 최소화해야 한다.

#### 근사해의 정밀도(Precision)

정밀도(precision)는 근사해가 참값에 얼마나 근접한가를 보는 것이 아니라, 여러 번 반복 측정하거나 반복 계산을 했을 때 결과들이 서로 얼마나 가까운가를 나타내는 개념이다. 가령 똑같은 문제에 대해 여러 가지 방법을 적용하거나, 혹은 같은 알고리즘을 반복해서 사용할 때 근사해들이 서로 얼마나 일관성을 유지하는지 살피는 지표라고 할 수 있다.

통계적 실험에서 측정한 값을 여러 번 반복해서 얻는 상황을 예로 들어보면, 측정값들이 서로 모여 있는 분산의 정도가 정밀도를 나타낸다. 여기에서 참값을 알든 모르든 상관없이 결과값들끼리 상호 얼마나 가까운지를 측정하는 것은 가능하다. 수치해석에서도 반복 계산 시에 결과들의 편차가 크지 않다면, 해당 알고리즘이나 방법이 일정한 정밀도를 가진다고 할 수 있다.

정밀도는 데이터 처리 과정에서 발생하는 잡음이나, 계산 과정에서 나타나는 작은 불안정성에도 쉽게 흔들리지 않을 정도로 안정적인 결과 분포를 보이는가를 평가하는 개념이 되기도 한다. 따라서 어떤 알고리즘이 안정적으로 동작하는지, 혹은 입력 데이터나 중간 계산 값이 미세하게 바뀌었을 때 결과값들이 크게 변하지 않고 서로 근접한 형태를 유지하는지 등을 보는 척도가 될 수 있다.

#### 예시: 정밀도와 정확도의 비교

어떤 실제 문제에서 참값이 $x$라고 할 때, 여러 번의 근사 계산 결과가 $\hat{x}*{1}, \hat{x}*{2}, \hat{x}\_{3}, \dots$로 나타났다고 하자. 만약 이 결과들이 모두 참값 $x$에서 크게 벗어나 있더라도, 서로 간에는 꽤 유사한 값을 보인다면 높은 정밀도를 가진다고 해석할 수 있다. 반대로, 어떤 결과가 참값과 아주 가깝지만 계산마다 그 값이 들쑥날쑥하게 변한다면 높은 정확도를 가질지언정 낮은 정밀도를 가질 수 있다.

정밀도와 정확도를 함께 고려하려면, 참값에 얼마나 가까운지(정확도)와 반복 계산 시 결과가 안정적인지(정밀도)라는 두 축을 동시에 살펴야 한다. 이를 수학적으로 풀어서 보면, 정확도는 $|x - \hat{x}|$가 매우 작아야 한다는 의미이고, 정밀도는 $|\hat{x}*{i} - \hat{x}*{j}|$가 충분히 작아야 한다는 의미로 해석할 수 있다.

#### 오차의 벡터적 해석

해당 문제가 스칼라 값이 아니라 벡터 값 $\mathbf{x} \in \mathbb{R}^{n}$에 대한 근사해 $\mathbf{\hat{x}}$로 확장된다고 해도 동일한 원리가 적용된다. 즉,

$$
\mathbf{x} - \mathbf{\hat{x}}
$$

는 참해와 근사해의 차이를 나타내는 벡터이고, 이 벡터의 **노름**을 통해 오차의 크기를 측정할 수 있다. 예컨대, 유클리드 노름(2-노름)을 사용하면

$$
|\mathbf{x} - \mathbf{\hat{x}}|*{2} = \sqrt{(x*{1}-\hat{x}*{1})^{2} + \cdots + (x*{n}-\hat{x}\_{n})^{2}}
$$

가 절대 오차에 대응하며,

$$
\frac{|\mathbf{x} - \mathbf{\hat{x}}|*{2}}{|\mathbf{x}|*{2}}
$$

는 상대 오차에 대응하게 된다. 벡터 해석에서도 마찬가지로 정밀도는 여러 번 계산했을 때 벡터 근사해 $\mathbf{\hat{x}}*{i}$들 사이의 분산 혹은 상호 간의 거리 $|\mathbf{\hat{x}}*{i} - \mathbf{\hat{x}}*{j}|*{2}$가 얼마나 작은지를 확인하는 것으로 해석할 수 있다.

#### 머신 이피실론과 근사해

컴퓨터로 수치 계산을 수행할 때, 유한 비트를 사용하는 부동소수점 연산의 특성상 미세한 오차가 누적되어 나타난다. 이를 단순히 '반올림 오차'라고 부르지만, 사실은 매우 복합적인 요인이 작용한다. 특정 숫자를 기계적으로 표현할 수 있는 정밀도의 한계를 수치해석에서는 종종 \*\*머신 이피실론(machine epsilon)\*\*으로 표현한다. 이 값은 현존하는 컴퓨터 시스템에서 부동소수점 연산이 표준화된 IEEE 754를 기반으로 어느 정도까지 '가장 가까운 유효 자릿수'를 유지할 수 있는지를 평가하는 기준이 된다.

머신 이피실론이 실제 연산 과정에서 정확도와 정밀도에 미치는 영향은 무시하지 못할 정도이다. 어떤 알고리즘이 이상적으로는 매우 높은 정확도를 보이더라도, 그 과정에서 계산되는 중간 값들이 머신 이피실론보다 훨씬 작은 차이를 구별하지 못한다면 실제 결과는 소수점 이하 일정 자릿수 이상에 대해서 의미가 퇴색할 수 있다. 다시 말해, 알고리즘상 계산 순서와 방식에 따라 정밀도나 정확도 측면에서 손실이 발생할 수 있다는 점이 강조된다.

#### 부동소수점 연산에서의 표현 한계

컴퓨터가 수를 표현하고 연산하는 과정은 일반적으로 IEEE 754 규격을 따른다. 이 규격에 따르면, 실수 값을 메모리에 저장할 때 유한 개의 비트만을 사용하여 유효숫자와 지수를 표현한다. 이는 이론적으로 $\mathbb{R}$ 전체에 대한 무한정의 표현을 제공하지 못하므로, 특정 구간 밖에 있는 값들은 ‘무한대’로 취급하거나, 유효숫자를 더 이상 늘일 수 없는 경우 반올림이 일어난다. 예를 들어, 어떤 실제 실수가 $r$이라고 할 때, 컴퓨터 내부에서는 $r$을 정확히 표현하지 못하고, 가장 가까운 표시 가능한 부동소수점 수 $fl(r)$로 대체한다.

수치해석적인 관점에서 이 차이는 상당히 중요한 문제를 야기한다. 이 차이가 누적되면 근사해가 수렴하더라도 실제로는 일정 수준 이하로 참값에 접근하지 못하는 상황이 발생한다. 예컨대 이론적으로 불가능한 큰 수나 극도로 작은 수가 계산 중간에 등장하는 경우, 부동소수점 오버플로(overflow)나 언더플로(underflow)가 일어나면서 계산 결과가 의도치 않게 0 혹은 무한대로 왜곡될 수 있다.

IEEE 754 규격에서 주어진 유효 자릿수를 벗어나는 값들은 $\pm \infty$, 혹은 0으로 수렴해버리기도 한다. 작은 값들의 경우, 정규화(denormalization) 등의 보조 기법이 적용될 수 있지만, 결국은 완벽한 표현을 보장하지 못한다. 이 점에서 근사해의 정확도와 정밀도를 동시에 관리하기 위해서는, 문제 규모나 알고리즘 복잡도가 증가할수록 중간 연산에서 발생하는 표현 한계를 주기적으로 점검하는 과정이 중요하다.

#### 연산 순서에 따른 오차 누적

부동소수점 산술은 일반적인 실수 연산의 결합법칙과 교환법칙이 깨질 수 있다. 즉,

$$
(a + b) + c \neq a + (b + c)
$$

가 성립할 수 있으며, 이는 실제 하드웨어 레벨에서 연산이 어떻게 일어나는지(레지스터 사용, 반올림 규칙, 피연산자의 스케일 차이 등)에 따라 그 결과가 상당히 달라진다. 따라서 어떤 함수를 계산할 때, 이론적으로 동등해 보이는 표현식이라도 실제 부동소수점 연산에서는 오차가 다르게 쌓일 수 있다.

예컨대, $a$와 $b$가 매우 큰 수이고 $c$가 매우 작은 수라고 하자. 이때 $b + c$ 연산은 반올림으로 인해 $b$ 자체와 같은 값이 되어버리고, 그 뒤 $a$와 더하면 결과적으로 $a + b$가 나온다. 반면 $(a + b) + c$는 우선 큰 수 끼리 합산이 이루어지고, 이후 $c$가 무시될 가능성이 높아진다. 이처럼 연산 순서와 방식에 따라 소멸 소수(cancellation) 등으로 인한 오차가 크게 달라질 수 있음을 의미한다.

알고리즘 설계 시에는 이처럼 연산 순서에 따른 반올림 오차 누적을 최소화하도록 주의 깊게 구현해야 한다. 예를 들어, 동등한 연산을 하더라도 작은 수부터 먼저 더하는 방식을 택하거나, 큰 수에서 작은 수를 뺄 때 나타나는 소멸오차를 줄이도록 중간 변수를 재조정하는 기법 등을 사용할 수 있다.

#### 정밀도와 유효숫자 개수

컴퓨터에서 어떤 수가 double precision(배정도 부동소수점)으로 표현될 때, 일반적으로 15\~16자리 정도의 십진 자릿수를 정확히 표현할 수 있는 것으로 알려져 있다. 이 말은 $10^{-15}$ 수준의 상대 오차 이내에서는 소수점 자릿수를 유지할 수 있다는 것을 뜻한다. 하지만 실제로는 연산이 여러 단계를 거치거나 매우 큰 수와 매우 작은 수를 섞어 계산할 때, 이 이론적 자릿수 이하로 정확도가 떨어질 수 있다.

정밀도를 정의할 때, 단순히 결과값 한 번의 표현을 보고 판단하기보다는 중간 연산 과정에서 반복해서 나타나는 미세 오차가 얼마나 누적되고 축적되는지를 살펴야 한다. 이 과정에서 필연적으로 표현되는 반올림 오차, 절단 오차(cut-off error) 등은 반복 계산마다 영향력을 행사한다. 따라서 결과가 서로 유사한지(정밀도), 참값에 충분히 가까운지(정확도)를 평가하고자 한다면, 가능한 여러 입출력 조건이나 다양한 연산 경로를 시뮬레이션하여 분석해보는 것이 필요하다.

#### 근사해 품질 평가의 다층적 접근

근사해의 품질을 평가할 때, 한편으로는 참값(혹은 높은 신뢰도의 기준 해)과의 차이를 평가하고(정확도), 다른 한편으로는 반복 계산 시 결과들이 얼마나 안정적으로 모이는지를 본다(정밀도). 여기에 추가로, 계산 과정에서 사용되는 자원(메모리, 시간), 알고리즘의 계산 복잡도, 입력 데이터의 불확실성 등이 서로 얽혀 있는 상황이 많다.

정밀도가 높게 나왔더라도, 계산 결과가 실제로는 참값에 크게 빗나가 있다면 유의미한 해라고 말하기 어렵다. 반대로, 정확도가 높게 관측되더라도, 매번 계산할 때마다 결과의 분산이 지나치게 크다면 이를 실용적으로 활용하기 어렵다. 결국 문제의 특성, 모델링 목적, 계산 비용 등을 종합적으로 살피면서 오차 해석을 해야 한다.

이렇듯 수치해석에서는 해의 근사 과정뿐 아니라, 근사해 자체가 문제의 실제 해석이나 응용 단계에서 어떤 의미를 가지는지도 꼼꼼히 살펴야 한다. 모델 식 자체가 잘못 설정되었거나, 입력 데이터가 불완전하거나, 수치 해석 알고리즘이 불안정(stability 문제)하다면, 정밀도나 정확도를 아무리 잘 관리해도 실제 활용 가능성은 떨어질 수밖에 없다.

#### Ill-Conditioned 문제와 알고리즘 안정성

어떤 수치 문제를 풀 때, 입력값이나 중간 계산값에 미세한 변동이 발생했을 때 결과값이 크게 요동한다면 이 문제를 **ill-conditioned**되었다고 한다. 반대로, 해당 변동이 결과값에 비교적 작게 반영되는 문제는 **well-conditioned**되었다고 평가한다. 문제의 조건수(condition number)가 큰 값으로 나타날수록 ill-conditioned 문제가 될 가능성이 높다.

예를 들어, 어떤 함수 $f(\mathbf{x})$에 대해 $\mathbf{x}$가 소량 $\delta \mathbf{x}$만큼 변했을 때 결과가 크게 바뀐다면, $f(\mathbf{x})$ 자체가 ill-conditioned 문제에 해당할 수 있다. 구체적으로, 스칼라 함수의 경우, 조건수 $\kappa(x)$를 정성적으로

$$
\kappa(x) = \left| x \frac{f'(x)}{f(x)} \right|
$$

등으로 나타낼 수 있으며, 벡터나 행렬 연산에 대해서는 적절한 노름을 기준으로 조건수를 정의한다. 예컨대 선형 시스템 $\mathbf{A}\mathbf{x} = \mathbf{b}$에 대해, 행렬 $\mathbf{A}$의 조건수는

$$
\kappa(\mathbf{A}) = |\mathbf{A}| |\mathbf{A}^{-1}|
$$

로 정의되며, 이 값이 클수록 입력이나 중간 연산에서 발생하는 오차가 결과값에 증폭되기 쉬운 ill-conditioned 문제임을 의미한다.

ill-conditioned 문제에서는 아무리 알고리즘을 엄밀하게 구현하고 반올림 오차를 줄이려 해도, 근본적으로 미세한 오차가 결과를 크게 왜곡할 위험이 존재한다. 따라서 근사해의 정확도와 정밀도 모두가 떨어질 가능성이 커진다. 이런 경우, 문제를 재구성(preconditioning)하거나, 알고리즘 자체를 좀 더 수치적 안정성(stability)을 갖춘 형태로 개선해야 한다.

알고리즘이 얼마나 오차를 증폭시키지 않고 안정적으로 결과를 산출하는지는 **안정성**(stability)의 개념으로 평가한다. 일반적으로 알고리즘은 \*\*전방오차(forward error)\*\*와 **후방오차(backward error)**, 그리고 이를 통해 파악되는 조건수와의 관계를 종합적으로 분석하여 안정성을 판별한다. 예컨대, backward stable한 알고리즘은 오차가 마치 입력 값에 미세한 교란이 있었던 것과 동등하게 해석될 수 있음을 의미한다. 이는 실제 계산 중 발생하는 수치적 잡음을 입력 데이터의 일부로 간주해도 결과가 크게 달라지지 않는 알고리즘임을 뜻한다.

#### 전방오차와 후방오차

전방오차(forward error)는 알고리즘을 통해 나온 결과 $\mathbf{\hat{x}}$와 참해 $\mathbf{x}$ 자체 사이의 차이를 직접적으로 측정하는 것이다. 예를 들어,

$$
\text{전방오차} = |\mathbf{x} - \mathbf{\hat{x}}|
$$

는 직접적으로 결과물과 참값 사이의 차이를 의미한다. 한편, 후방오차(backward error)는 알고리즘이 실제로 풀고 있는 문제와 원래 문제의 차이에 주목한다. 즉, 알고리즘으로 인해 약간 변형된 문제를 다음과 같이 정의하고, 그 문제가 가진 참값과 실제 결과의 일치도를 살핀다.

가령, $\mathbf{A}\mathbf{x} = \mathbf{b}$ 문제를 풀 때, 실제로는 $\mathbf{A} + \Delta \mathbf{A}$, $\mathbf{b} + \Delta \mathbf{b}$라는 조금 다른 문제를 해석적으로 풀었을 때의 해와 계산 결과 $\mathbf{\hat{x}}$가 일치한다고 간주한다면,

$$
(\mathbf{A} + \Delta \mathbf{A})\mathbf{\hat{x}} = \mathbf{b} + \Delta \mathbf{b}
$$

을 만족한다. 이때 $\Delta \mathbf{A}$, $\Delta \mathbf{b}$가 충분히 작다면, 알고리즘이 발생시킨 오차는 ‘원래 문제를 조금 교란시킨 결과’로 해석될 수 있다는 의미가 된다. 이처럼 후방오차는 원래 문제와 조금 다른 문제를 풀었다고 봤을 때 그 차이가 얼마나 작은지를 측정하는 개념이어서, 알고리즘 안정성 해석에 중요한 정보를 제공한다.

#### 근사해 오차 분석을 위한 실제적 접근

조건수가 큰 ill-conditioned 문제이거나, 부동소수점 연산에 따른 오차가 많이 누적되는 상황이라면, 오차 분석이 단순히 전방오차만 보는 것으로는 부족하다. 알고리즘의 후방안정성이나, 알고리즘 수행 단계에서 발생하는 중간 오차가 결과에 어떤 경로로 전파되는지 등을 세밀하게 따져봐야 한다.

문제 구조 자체를 재편성하여 더 나은 수치적 특성을 갖도록 하는 **preconditioning** 기법이나, 정규화(normalization) 기법 등을 사용하기도 한다. 또한, 반복법(iterative method)을 사용하는 경우라면 수렴 과정에서 round-off 오차가 어떤 패턴으로 축적되는지를 모니터링하여, 특정 단계마다 ‘재정렬’, ‘재설정’ 작업을 수행하는 식으로 오차를 방어적으로 처리하기도 한다.

이처럼 근사해의 정확도와 정밀도를 향상시키려면, 알고리즘의 설계뿐 아니라 문제 설정, 데이터 스케일링, 부동소수점 표현 방식, 연산 순서 제어, 그리고 후방오차 해석까지 포괄적으로 검토해야 한다. 예를 들어, 단순히 반복 횟수를 늘린다고 해서 꼭 더 정밀한 해를 얻으리라는 보장은 없다. 오히려 반복 횟수를 늘릴수록 축적 오차가 더 커지거나, 불안정 구간에 접어들면 결과가 오히려 악화될 수도 있다.

#### 반복해법에서의 오차 축적과 정밀도

직접해법(direct methods)과 달리, 반복해법(iterative methods)은 초기 추정값에서 시작하여 단계적으로 해를 업데이트해가는 방식이다. 예를 들어, 선형 시스템 $\mathbf{A}\mathbf{x} = \mathbf{b}$에 대해 Jacobi, Gauss-Seidel, 혹은 CG(Conjugate Gradient)와 같은 반복법을 사용할 수 있다. 이때 각 단계에서 새로운 근사해 $\mathbf{\hat{x}}\_{k+1}$를 얻고, 특정 종료 조건을 만족할 때까지 과정을 지속한다.

이러한 반복해법에서 정밀도와 정확도는 다음과 같은 맥락으로 분석된다. 먼저, 각 반복 단계에서 잔차(residual)

$$
\mathbf{r}*{k} = \mathbf{b} - \mathbf{A}\mathbf{\hat{x}}*{k}
$$

를 살펴봄으로써 알고리즘이 참해에 점차 가까워지는지 모니터링할 수 있다. 단순히 잔차 $|\mathbf{r}\_{k}|$가 줄어드는 것만으로는 충분치 않으며, 잔차에 대한 조건수의 효과와 반올림 오차 누적도 고려해야 한다. 매우 작은 잔차라도, ill-conditioned 문제에서는 실제 해와 거리가 여전히 클 수 있기 때문이다.

반복 단계가 진행되면서 round-off 오차가 누적되면, 이론상으로는 수렴해야 하는 알고리즘임에도 불구하고 일정 시점 이후에는 오히려 오차가 더 커지거나, 수렴 속도가 급격히 떨어질 수 있다. 이를 **stalemate** 현상 또는 **round-off plateau** 현상으로 부르기도 한다. 이러한 문제는 특히 고차원 문제에서 대규모 연산이 이뤄지거나, 중간 단계마다 매우 큰 수와 매우 작은 수가 섞여 계산될 때 더욱 잘 드러난다.

반복해법을 사용할 때, 특정한 수렴 기준을 설정하고 그에 도달했을 때 알고리즘을 중단하는 것이 일반적이다. 예를 들어, 다음과 같이 잔차 기반의 상대 오차 조건을 둘 수 있다.

$$
\frac{|\mathbf{r}\_{k}|}{|\mathbf{b}|} < \epsilon
$$

이때 $\epsilon$은 원하는 정확도 수준을 나타내며, 너무 작게 설정하면 알고리즘이 후방오차를 극복하기 위해 지나치게 많은 반복을 수행할 수도 있다. 반면 $\epsilon$이 너무 크면 아직 충분히 참값에 가깝지 않은 상태에서 해를 구했다고 잘못 판단할 위험이 있다.

#### 사전(에러 추정)과 사후(에러 평가) 기법

수치 알고리즘에서는 오차 추정을 위해 사전적(a priori) 분석과 사후적(a posteriori) 분석을 활용한다. 사전적 분석은 알고리즘 설계 단계에서 이론적인 오차 한계를 미리 추정하는 기법을 말한다. 예컨대, 반복해법에서 수렴 속도를 미분방정식 해석이나 선형대수학적 고찰을 통해 이론적으로 규정하고, 그 과정에서 반올림 오차의 누적을 상한선으로 두는 식이다.

사후적 분석은 알고리즘이 실제로 산출한 근사해에 대한 오차를 외부 정보나 내부 잔차를 활용해 평가하는 방식이다. 예컨대, 결과값 $\mathbf{\hat{x}}$를 얻은 뒤, $\mathbf{r} = \mathbf{b} - \mathbf{A}\mathbf{\hat{x}}$를 계산해보고 $|\mathbf{r}|$가 어느 정도인지 확인함으로써 해가 실제 문제에 얼마만큼 부합하는지 정성적으로 판단한다. 여기에 $\mathbf{A}$의 조건수 정보 등을 종합하면, 참해와의 거리 $|\mathbf{x} - \mathbf{\hat{x}}|$를 어느 정도 추정할 수 있다.

이러한 사전 및 사후 오차 평가 기법은 실전 수치해석에서 필수적이다. 예를 들어, 유한요소법(FEM) 같은 편미분방정식 근사해 문제에서도 메쉬(mesh) 크기가 작아지면 이론상 절단 오차가 줄어 정확도는 증가하지만, 동시에 연산량과 round-off 오차 누적도 커질 수 있다. 이때 이론적(a priori) 오차 추정, 그리고 실제 계산 후 잔차 기반(a posteriori) 에러 평가를 통해 메쉬 크기를 적절히 조정하는 접근이 보편적이다.

#### 임계 영역에서의 신뢰도

오차 분석을 통해 적절한 알고리즘을 골라 쓰더라도, 실제 계산 과정에서는 여러 “임계 영역(critical region)”이 존재할 수 있다. 예컨대, 특정 매개변수나 초기값을 조금만 달리해도 알고리즘의 수렴 특성이 크게 변하거나, 결과값이 급격히 변동하는 구간 등이 나타날 수 있다. 이런 구간에서는 오차 분석을 더욱 세밀하게 하여, 근사해의 정확도 및 정밀도를 보장하는지 반복적으로 체크해야 한다.

여기에 더해, 실제 응용에서 사용하는 알고리즘이 반복해서 ‘재귀적’ 계산을 수행할 때, 각 단계 오차가 다음 단계로 전파되는 구조가 나타난다. 편미분방정식의 시간적 적분에서 time-stepping 기법을 사용하는 예를 떠올려보면, 이전 시간 스텝의 오차가 다음 스텝에 누적되면서 전체 시뮬레이션 결과를 오염시킬 수 있다. 이를 방지하기 위해 적절한 안정 조건과 step-size 제어, 재보정 등 다양한 기법이 동원된다.

이와 같이, 근사해의 정밀도와 정확도를 높이기 위해서는 이론적 오차 한계치를 이해하는 것은 물론, 실제 계산 과정과 문제 구조 양쪽에서 발생할 수 있는 오차 요인을 동시에 고려해야 한다. 문제 상황과 목적에 따라 어느 한쪽만 놓쳐도, 전반적인 계산 결과의 신뢰도가 크게 흔들릴 수 있다.

#### 절단오차(Truncation Error)와 반올림오차(Round-off Error)

수치해석에서 오차는 크게 \*\*절단오차(truncation error)\*\*와 \*\*반올림오차(round-off error)\*\*의 두 축으로 구분할 수 있다. 절단오차는 일반적으로 이론적인 무한 급수나 무한 반복을 실제 계산에서 유한하게 끊어서 생기는 오차를 일컫는다. 예컨대, 미분방정식을 해석적으로 풀면 무한 급수 형태의 해가 등장할 때가 많으나, 수치 계산에서는 이를 적절한 차수에서 멈추거나(테일러 전개 절단), 일정 구간 간격으로 근사(유한차분, 유한요소 등)함으로써 오류가 발생한다.

반면, 반올림오차는 유한 비트를 사용하는 부동소수점 표현 방식으로 인해 발생하는 오차를 의미한다. 컴퓨터는 $r$이라는 임의의 실수를 $fl(r)$이라는 가장 가까운 ‘표현 가능한 부동소수점 수’로 둔갑시켜 연산을 진행한다. 이때, 각 단계에서 조금씩 생기는 미세한 차이가 반복 계산을 거치며 점차 누적되는 현상이 round-off error의 본질이다.

#### 절단오차와 근사방법 설계

절단오차는 주어진 수치 알고리즘(또는 근사 기법)의 **이론적 정밀도**와 밀접하게 관련된다. 예컨대, 테일러 전개를 이용해 $f(x+h)$를 근사한다고 하면,

$$
f(x+h) = f(x) + h f'(x) + \frac{h^{2}}{2!} f''(\xi)
$$

와 같은 식으로 정의할 수 있다(여기서 $\xi$는 $x$와 $x+h$ 사이의 어떤 점으로, 테일러 정리의 잔차항을 보여준다). 만약 $h$가 매우 작으면 $f(x+h)$를 $f(x) + h f'(x)$로만 근사하고, 나머지 항을 무시함으로써 절단오차가 발생한다. 이때 오차는 이론적으로 $O(h^{2})$의 크기를 갖는다는 식으로 표현될 수 있다.

편미분방정식을 푸는 유한차분법(FDM)이나 유한요소법(FEM), 혹은 수치적 적분에서도 유사한 개념이 적용된다. 예를 들어, 어떤 적분

$$
I = \int\_{a}^{b} f(x),dx
$$

를 수치적으로 근사하기 위해 사다리꼴 공식, 심프슨 공식 등을 쓴다면, 이들 각 공식은 구간을 일정한 간격으로 분할하고 분할점에서의 함수값을 이용해 근사적 합을 만든다. 그 과정에서 이론적 성질에 따라 $O(h^{2})$, $O(h^{4})$ 등으로 표현되는 절단오차가 나타난다. 이 절단오차의 계수를 줄이거나 더 높은 차수의 근사를 쓰면(고차수 기법), 이론적으로는 정확도가 올라가지만, 반대로 round-off error가 증가하거나 계산 비용이 매우 커질 수 있다.

#### 반올림오차와 연산 순서

반올림오차는 $10^{-15}$ 수준 이하의 미세한 차이라 하더라도, 연산 횟수가 매우 많은 경우 누적되면서 최종 결과를 크게 왜곡할 수 있다. 특히 \*\*catastrophic cancellation(치명적 상쇄)\*\*이라 불리는 상황이 잘 알려진 예시다. 이는 큰 수 두 개가 서로 거의 비슷한 값을 가질 때, 이들을 빼면 유효숫자가 갑자기 급격히 사라지는 현상을 말한다. 예를 들어,

$$
a \approx b \quad\Rightarrow\quad a - b \approx 0
$$

인데, 실제 계산에서는 $a$와 $b$가 소수점 이하 몇 자릿수에서만 차이가 있는 경우, 이를 뺀 결과값은 극도로 적은 유효숫자만 남게 된다. 이처럼 중간 연산에서 오차가 급격히 늘어날 수 있기 때문에, 수치 알고리즘 설계 시에는 빼기 연산의 상대적 순서나 대안적 표현식 선택에 각별히 유의한다.

#### 비선형 방정식 근사에서의 오차

비선형 방정식을 풀 때 대표적으로 사용하는 뉴턴 방법(Newton’s method)을 예로 들면,

$$
x\_{k+1} = x\_{k} - \frac{f(x\_{k})}{f'(x\_{k})}
$$

와 같은 반복 공식을 사용한다. 이때, 뉴턴 방법은 보통 2차 수렴(quadratic convergence)을 보여서 반복마다 오차가 매우 빠르게 줄어든다. 하지만 $f'(x)$가 매우 작은 값일 때(혹은 0에 가까울 때), 위 식 자체가 큰 수와 작은 수의 조합이 되어 반올림오차가 비약적으로 커질 우려가 있다.

또한, 뿌리가 여러 개 존재하는 비선형 방정식에서 시작점 $x\_{0}$를 어떻게 잡느냐에 따라 다른 근사해에 수렴하거나 수렴이 불안정해지는 경우가 발생한다. 이런 상황에서 반복 중 $f'(x\_{k})$가 반올림오차로 인해 실제 0값으로 처리되거나, 무한대에 가까운 값을 만들어 버리면 알고리즘이 오작동을 일으킬 위험이 커진다. 따라서 수치 안정성을 고려하여 적절히 초기값을 선택하고, $f'(x)$가 작은 구간에 진입할 가능성이 있을 때 보조 방안을 마련해두는 것이 권장된다.

#### 미분방정식 해석에서의 정밀도와 적분 스텝

상미분방정식(ODE)을 수치적으로 풀기 위해 오일러(Euler) 방법, 런지-쿠타(Runge-Kutta) 계열의 방법 등을 사용할 때, \*\*로컬 절단오차(local truncation error)\*\*와 \*\*글로벌 절단오차(global truncation error)\*\*를 구분하여 분석한다.

로컬 절단오차는 한 스텝 내에서 정확해 대비 근사해가 가지는 오차를 의미한다. 예를 들어, 오일러 전진법

$$
y\_{k+1} = y\_{k} + h,f(t\_{k}, y\_{k})
$$

은 한 스텝에서 $O(h^{2})$의 로컬 절단오차를 갖는 것으로 알려져 있다.

글로벌 절단오차는 $t\_{0}$에서 $t\_{N}$까지 전체 구간을 통틀어 누적되는 오차로서, 오일러 전진법의 경우 $O(h)$ 수준이다. 즉, 스텝 크기 $h$를 반으로 줄이면 오차가 대략 절반으로 줄어든다. 하지만 너무 작은 $h$를 쓰면 round-off error가 반대로 쌓여서 전체 계산 정확도가 떨어지는 역설적 상황이 발생할 수도 있다.

런지-쿠타 4차 방법(RK4)은 한 스텝에서 $O(h^{5})$ 로컬 절단오차, $O(h^{4})$ 글로벌 절단오차를 가지므로 적당한 스텝 크기를 고르면 오일러 방법보다 훨씬 더 정확도가 높다. 다만, 스텝 하나당 4번의 기울기(slope) 평가가 필요하므로 계산 부하도 증가한다. 결국 수치해석 실무에서는 적절한 **adaptive step-size** 기법을 활용하여, 오차를 목표 범위 안에 유지하면서도 불필요한 계산 낭비를 막는다.

#### 간단한 예시: Python을 이용한 ODE 수치해

다음은 파이썬(Python)에서 단순 오일러 방법으로 1차 ODE를 푸는 예시를 보여준다. 오차가 어떻게 정밀도, 정확도에 영향을 끼치는지를 간단히 살펴볼 수 있다.

```python
import numpy as np
import matplotlib.pyplot as plt

# dy/dt = f(t, y) = -y, y(0) = 1
# 실제 해 : y(t) = e^(-t)

def f(t, y):
    return -y

def euler_method(f, y0, t0, tf, h):
    t_vals = [t0]
    y_vals = [y0]
    
    t = t0
    y = y0
    
    while t < tf:
        y = y + h * f(t, y)
        t = t + h
        t_vals.append(t)
        y_vals.append(y)
    return np.array(t_vals), np.array(y_vals)

# 파라미터
y0 = 1.0
t0 = 0.0
tf = 5.0
h = 0.1

t_arr, y_arr = euler_method(f, y0, t0, tf, h)
y_exact = np.exp(-t_arr)

# 오차 계산
abs_error = np.abs(y_exact - y_arr)
rel_error = abs_error / np.abs(y_exact)

plt.figure(figsize=(8,5))
plt.plot(t_arr, y_arr, 'ro-', label='Euler Approx')
plt.plot(t_arr, y_exact, 'b-', label='Exact')
plt.title("Euler Method vs Exact Solution")
plt.xlabel("t")
plt.ylabel("y")
plt.legend()
plt.show()

plt.figure(figsize=(8,5))
plt.plot(t_arr, abs_error, 'g-', label='Absolute Error')
plt.plot(t_arr, rel_error, 'm-', label='Relative Error')
plt.title("Error Analysis")
plt.xlabel("t")
plt.ylabel("Error")
plt.legend()
plt.show()
```

위 코드에서 $y'(t) = -y(t)$, $y(0) = 1$라는 간단한 ODE를 풀이한다. 실제 해는 $y(t) = e^{-t}$이므로, 결과값을 비교하여 오차를 시각적으로 확인할 수 있다. 스텝 크기 $h$를 달리해보면, 절단오차와 round-off error가 어떻게 교차 작용하는지 직접 관측 가능하다.

#### mermaid를 이용한 근사해 오차 분석 개념도

아래 다이어그램은 전체적인 근사해 오차 분석 과정을 시각화한 것이다.

{% @mermaid/diagram content="flowchart LR
A\["문제 정의<br/>(방정식, ODE 등)"] --> B\["수치 알고리즘 설계<br/>(반올림/절단오차 고려)"]
B --> C\["근사해 계산<br/>(부동소수점 연산)"]
C --> D\["오차 평가<br/>(정확도/정밀도 분석)"]
D --> E\[조건수/안정성<br/>후방오차 등 점검]
E --> F\["결과 해석 및 개선<br/>(스텝 크기, 알고리즘 수정)"]
F --> C" %}

여기서 A\~F에 이르는 단계 각각에서 정밀도(반복 결과의 일관성)와 정확도(참해와의 근접도)가 중요한 역할을 담당하며, 이 두 가지 척도를 잘 관리하는 것이 수치해석 문제 해결의 핵심 과제 중 하나이다.

#### 복합적 관점의 오차 예측과 해석

수치해석에서 오차 분석은 단순히 근사해와 참값 사이의 차이를 알아내는 것에 그치지 않고, 다양한 각도에서 동시에 접근한다. 예컨대, 전산유체역학(CFD)이나 전산구조역학(CSM) 같은 분야에서는 방정식을 유한차분법 혹은 유한요소법으로 근사해를 구할 때, 해공간의 크기(메쉬 또는 그리드의 세분화 정도), 시간적 적분 스텝, 그리고 비선형 해석 알고리즘의 반복 정도가 모두 오차에 영향을 미친다.

이때 오차가 여러 단계에서 누적 또는 증폭될 수 있으므로, 각 과정의 오차 기여도를 분리해서 생각하거나, 반대로 종합해서 판단해야 한다. 예를 들어, 아래와 같이 세 종류의 부분 오차를 가정할 수 있다.

$$
E\_{\text{model}} + E\_{\text{method}} + E\_{\text{machine}} = E\_{\text{total}}
$$

여기서

* 모델링 오차 $E\_{\text{model}}$은 실제 물리계나 실제 현상과 달리 모델 식이나 경계조건을 단순화해서 사용했을 때 발생하는 차이를 의미한다.
* 방법론적 오차 $E\_{\text{method}}$는 유한차분, 유한요소 등 근사법 자체에서 생기는 절단오차 및 불완전한 수렴 등과 연결된다.
* 머신 오차 $E\_{\text{machine}}$는 부동소수점 표현과 연산으로 인해 불가피하게 발생하는 반올림오차를 가리킨다.

현실적으로는 세 부류의 오차가 뒤섞여 나타나므로, 분석 시에는 어느 부분이 지배적인 요인인지를 파악하는 것이 중요하다. 모델링 오차가 매우 크다면, 아무리 높은 차수의 근사법을 사용해도 참현상과의 거리가 여전히 클 수밖에 없고, 머신 오차가 극히 중요한 구간이라면 알고리즘 자체를 변경하거나, 고정소수점 연산이나 임의정밀도 연산 등 특수한 방식을 도입하는 방안도 검토할 수 있다.

#### 유효 자릿수(Significant Figures) 관점

일상적인 공학 계산에서는 근사해의 ‘유효 자릿수(significant figures, sig figs)’가 얼마나 보장되는지가 하나의 실용적 지표가 된다. 예를 들어, 근사해가 소수점 이하 3자릿수 수준의 정확도를 가진다면, 실험 결과나 다른 시뮬레이션과 대조했을 때 최소 세 자릿수까지는 의미 있는 값을 비교할 수 있다는 뜻이 된다.

공학적, 과학적 계산에서 5~~6자리 이상의 정확도가 사실상 요구되는 경우도 있지만, 반대로 모델 자체가 대략적이어서 2~~3자리 신뢰도만 있어도 충분한 응용이 많다. 이때 중요한 것은, 단순히 결과 출력 자릿수를 늘리는 것(예: printf("%.10f", x))만으로 정확도를 보장할 수 없다는 점이다. 내부 계산 과정에서 오차가 이미 누적되었다면, 출력이 아무리 많은 자릿수를 보여줘도 실제로는 쓸모없는 “가짜 자릿수”가 포함될 수 있다.

#### 오차 전파(Error Propagation)의 일반식

오차 전파 이론에서 한 예를 들어 보면, 두 실수 변수가 각각 $x, y$라 할 때 이들의 참값에 대한 오차를 $\delta x, \delta y$라고 하자. 어떤 함수

$$
z = f(x, y)
$$

를 생각하면, $z$에 대한 오차 $\delta z$는 1차 근사 수준에서 다음과 같이 전개할 수 있다.

$$
\delta z \approx \frac{\partial f}{\partial x}\bigg|*{(x,y)} ,\delta x + \frac{\partial f}{\partial y}\bigg|*{(x,y)} ,\delta y
$$

이는 테일러 전개의 1차 항만 고려한 것으로, $\delta x, \delta y$가 매우 작을 때 유용하다. 벡터 $\mathbf{x}$가 여러 개의 컴포넌트를 가지는 일반적 상황으로 확장해도 같은 원리가 적용된다.

수치해석에서 각 단계마다 입력으로 들어오는 $\mathbf{x}$와 알고리즘 내부 변수가 가지는 작은 오차들이 점차 함수 $f$를 통해 출력으로 전파되어, 결과값 $\mathbf{z}$에서 예상되는 오차 $\delta \mathbf{z}$를 추정할 수 있다. 이때 $\delta \mathbf{z}$가 초기 $\delta \mathbf{x}$에 비해 크게 증폭되는 경우를 **민감한(sensitive)** 계산이라고 부르며, 이는 곧 ill-conditioned 문제와 맞물려 있음을 시사한다.

#### 오차 해석의 실제 적용

수치해석 문제를 다룰 때, 다음과 같은 실제 적용 사례가 자주 언급된다. (아래 예시는 일반 서술로만 제시한다.)

고차 다항식 근 찾기: 고차 다항 방정식의 근을 찾을 때, 특정 구간 안에 서로 근접한 두 근이 있을 경우 부동소수점 연산으로 인해 그 두 근이 실제론 서로 다른 해임에도 불구하고 하나로 합쳐져버리는 현상이 발생할 수 있다. 혹은 높은 차수에서 계수가 무시될 정도로 작아지면, 그 계수 자체가 0으로 근사되어서 방정식의 특성이 크게 변질될 수 있다.

고유값 문제(Eigenvalue Problem): 행렬 $\mathbf{A}$의 고유값을 구할 때, 서로 인접한 고유값끼리 섞여버리거나, 거의 중복된 고유값이 부동소수점 오차로 인해 엉뚱한 값으로 갈라질 수 있다. 예컨대 대칭행렬에 대한 고유분해 알고리즘에서 이러한 수치적 분리(separation)가 실패하면, 사실상 한 덩어리로 엉겨 있는 형태의 근사해가 나온다.

최적화 문제(Optimization): 다변수 함수의 최소값을 찾는 과정에서, 구배(gradient)가 아주 작은 영역을 지나가거나, 해가 서로 가까운 복수의 지역 최소점이 있을 경우, 반올림오차로 인해 알고리즘이 임의의 지점으로 흘러갈 수 있다. 특히 스텝 크기나 라인 서치(line search)에서 값이 과도하게 반올림되면, 정상적이어야 할 수렴 과정이 크게 휘청거리게 된다.

이러한 예시들은 근사해의 “정밀도와 정확도”가 단순한 이론적 범위를 넘어, 실제 계산 과정에서 어떻게 극적으로 흔들릴 수 있는지를 잘 보여준다.

#### 후속 단계: 알고리즘 개선과 진단

오차 해석 결과, 문제가 지나치게 민감하거나 ill-conditioned로 판명되면, 알고리즘 개선이나 문제 재구성(preconditioning) 같은 접근법을 고려해야 한다. 예를 들어,

SVD(특잇값 분해), QR 분해 등을 사용하여 행렬을 안정적인 형태로 변환한 뒤 문제를 풀면, 고유값 문제나 선형회귀 문제 등에서 round-off 오차에 좀 더 안전해질 수 있다.

복수의 근을 가지는 방정식을 다룰 때, 특수한 root finding 기법을 적용하거나, 초기 추정값을 여러 군데에서 설정해 병렬로 해석함으로써 해가 합쳐지거나 소실되는 현상을 방지할 수 있다.

고정소수점 연산 또는 임의정밀도(arbitrary precision) 라이브러리를 활용하여, 부동소수점 한계가 심각하게 해를 왜곡하는 경우를 보완할 수 있다. 물론 이 경우 계산 비용이 커지는 단점이 따른다.

결국 **오차 분석 결과**는 단지 이론적인 수치해석 교과서의 개념이 아니라, 실제 계산 구현체에서 장단점을 파악하고, 그에 따라 적절한 대안을 마련하는 실무 지침이 된다.

#### 고정소수점 연산과 임의정밀도 연산

부동소수점 대신 고정소수점 연산 방식을 사용하는 분야도 있다. 예를 들어, 특정 임베디드 시스템이나 FPGA 설계에서는 자원 제약상 32비트 또는 16비트의 고정소수점을 쓰기도 한다. 이때 표현 가능한 값의 범위가 좁아지지만, 반올림 규칙이 단순해지고 일관된 연산 결과를 얻을 수 있다는 장점이 있다. 반면, 동적 범위가 제한되므로 언더플로나 오버플로가 쉽게 발생할 수 있으며, 특정 구간을 넘는 값을 다룰 때는 별도의 스케일링(scale factor) 작업이 필수적이다.

반대로 임의정밀도(arbitrary precision) 연산 라이브러리를 적용하면, 원하는 만큼 정밀도를 확장할 수 있다. 예를 들어 Python의 `decimal` 또는 `fractions` 모듈, C++의 GMP/MPFR 라이브러리 등을 활용하면, 부동소수점 한계를 넘어서 상당히 많은 자릿수를 유지한 상태로 계산을 진행할 수 있다. 하지만 그만큼 연산 속도가 눈에 띄게 느려진다는 점을 감수해야 하며, 데이터 구조 자체도 부동소수점과 달라서 알고리즘을 수정해야 하는 경우가 생긴다.

일반적으로 수치해석 문제에서 특정 구간은 근사연산이 허용되지만, 극도로 민감한 영역은 임의정밀도로 처리하여 안정성을 확보하는 **혼합 정밀도(mixed precision)** 기법이 연구되고 있다. 예컨대, 대규모 연산은 표준 double 정밀도로 진행하되, 일부 임계 연산(예: 역행렬을 구하는 단계)에는 고정밀도 연산을 써서 오류 누적을 방어하는 방식이다. 이는 현대 HPC(고성능컴퓨팅)에서 연산 효율과 정확도 모두를 고려하는 전략으로 주목받고 있다.

#### 수치 안정성과 에너지-보존적 특성

물리계나 공학계 문제에서는, 수학적으로 보았을 때 특정 보존량(에너지, 운동량 등)이 존재하는 경우가 많다. 예를 들어 해밀턴 시스템(Hamiltonian systems)에서는 이론적으로 총 에너지가 일정해야 하지만, 수치 해석을 통해 시뮬레이션할 때는 근사오차나 반올림오차로 인해 서서히 에너지가 소실되거나 증가하는 불안정 현상이 발생할 수 있다.

이를 해결하기 위해서는 **symplectic integrator** 같은 특수한 알고리즘을 사용하여, 에너지를 인위적으로 혹은 수리적으로 보존하도록 설계한다. 이와 같은 알고리즘들은 근사해가 시간을 따라가도 에너지가 일정하게 유지되도록 조정한다. 물론 이 과정에서 기본 오차 모델과는 다른 형태의 절단오차가 발생할 수 있으며, 그 성질을 면밀히 해석하는 작업이 필요하다. 하지만 결과적으로 보존해야 할 물리량을 지키면서 장기간 시뮬레이션했을 때 더 믿을 만한 결과를 얻을 수 있다.

#### Mixed Precision의 예시: C++ (MPFR 라이브러리)

아래는 C++에서 MPFR 라이브러리를 이용해 일부 고정밀도 연산을 수행하는 간단한 예시다. 실제로는 라이브러리 설치, 링킹, 헤더 포함 등이 필요하지만, 여기서는 개념 시연용 코드만 보여준다.

```python
#include <iostream>
#include <mpfr.h>

int main(){
    // 원하는 정밀도(비트 단위) 설정
    mpfr_t a, b, c;
    mpfr_init2(a, 200); // 200비트 정밀도
    mpfr_init2(b, 200);
    mpfr_init2(c, 200);

    // 10진수를 문자열로부터 읽어들이는 예시
    mpfr_set_str(a, "3.1415926535897932384626433832795", 10, MPFR_RNDN);
    mpfr_set_str(b, "2.7182818284590452353602874713527", 10, MPFR_RNDN);

    // c = a * b 연산
    mpfr_mul(c, a, b, MPFR_RNDN);

    // 결과 출력
    std::cout << "a = ";
    mpfr_out_str(stdout, 10, 0, a, MPFR_RNDN);
    std::cout << std::endl;

    std::cout << "b = ";
    mpfr_out_str(stdout, 10, 0, b, MPFR_RNDN);
    std::cout << std::endl;

    std::cout << "c = a * b = ";
    mpfr_out_str(stdout, 10, 0, c, MPFR_RNDN);
    std::cout << std::endl;

    mpfr_clear(a);
    mpfr_clear(b);
    mpfr_clear(c);

    return 0;
}
```

위 예시에서 `mpfr_init2(a, 200);`로 200비트 정밀도를 지정했다. 일반적인 double 정밀도가 53비트(대략 15\~16십진 자릿수) 정도를 제공하는 것에 비해, 여기서는 훨씬 많은 자릿수를 담을 수 있다. 만일 어떤 문제에서 원주율이나 자연상수의 값을 매우 정확히 유지해야 한다면, 이런 방식이 도움이 될 수 있다. 그러나 연산 속도와 메모리 사용량이 크게 증가한다는 점은 피할 수 없는 대가다.

#### 근사해와 불확실성

실험 데이터나 센서 데이터가 포함된 문제에서는, 측정값 자체가 이미 불확실성을 갖고 있기에, 엄밀한 의미의 참값 $x$를 특정하기 어렵다. 대신 확률적(統計的) 접근을 통해, $x$가 특정 확률분포를 가진 난수(random variable)로 보거나, 측정값에 대한 신뢰 구간(confidence interval)을 가정하는 식이다. 그런 다음, 수치 알고리즘 결과도 확률분포 혹은 신뢰 구간의 형태로 해석하게 된다.

이러한 불확실성 전파(uncertainty propagation) 기법은 최근 수치해석 및 베이시안(Bayesian) 통계 영역에서 활발히 다뤄진다. 가령, 입력 데이터가 (평균값 $\mu$, 표준편차 $\sigma$) 형태로 주어졌을 때, 알고리즘 결과의 통계적 변동을 여러 번의 몬테카를로(Monte Carlo) 시뮬레이션으로 추정할 수 있다. 이는 앞서 언급한 전방오차, 후방오차 개념을 확률론적으로 확장한 사례로 볼 수 있다.

#### 구간 연산(Interval Arithmetic)과 안전성

표준 부동소수점 연산에서는 어떤 수가 실제로는 $3.14\ldots$처럼 무한소수 형태이지만, 기계는 이를 제한된 자릿수만으로 잘라서 표현한다. 구간 연산(interval arithmetic)은 이러한 근본적 한계로부터 비롯되는 오차 전파 문제를 해소하기 위해, 모든 수를 실수가 아닌 ‘구간’으로 다루는 방식이다. 즉,

$$
x \in \[x\_{\text{low}},,x\_{\text{high}}]
$$

형태로 표현하고, 덧셈, 곱셈 등 연산을 할 때도 결과가 소속될 구간을 안전하게 추적한다. 예를 들어,

$$
\[x\_{\text{low}},,x\_{\text{high}}] + \[y\_{\text{low}},,y\_{\text{high}}]  =  \[x\_{\text{low}} + y\_{\text{low}}, , x\_{\text{high}} + y\_{\text{high}}].
$$

이 방식은 ‘최악의 경우’까지도 모두 포함하는 구간을 출력하기 때문에, 그 값이 진정 어디까지 치우칠 수 있는지를 보수적으로 예측할 수 있다.

일반적인 부동소수점 연산보다 구간 연산이 훨씬 엄격한 오차 경계를 제공하지만, 구간이 커질수록 결과 구간도 점차 커져서 유용성이 떨어지는 단점이 있다. 이는 수많은 연산이 이어질수록 구간이 기하급수적으로 팽창할 수 있기 때문이다. 따라서 구간 연산을 실용적으로 적용하기 위해서는, 적절한 수학적 테크닉(구간 축소, 분할 정복 접근 등)을 동원해 불필요하게 넓은 구간을 피하려고 노력한다.

그럼에도 구간 연산은 안전성이 최우선인 분야(예: 항공, 원자력, 의학 분야 등)에서 의미 있는 해법으로 꼽히며, 오류가 발생해도 그 영향 범위를 엄격히 추적할 수 있다는 점이 장점이다.

#### 확률적 라운딩(Stochastic Rounding)

최근에는 GPU 등에서 등장하기 시작한 확률적 라운딩 방식도 주목받고 있다. 표준 반올림 모드에서는 어떤 실수가 표현 범위 사이에 놓이면, 가장 가까운 부동소수점 값으로 정규화(normal rounding)를 한다. 확률적 라운딩은 그 대신 두 인접 표현 값 중 하나로 확률적으로 반올림하는 방식을 취한다. 예를 들어, 어떤 실제 값 $r$이 두 표현 가능한 값 $a$와 $b$ 사이에 있을 때,

$$
r \approx a \quad(\text{확률 } p), \quad r \approx b \quad(\text{확률 } 1 - p)
$$

형태가 된다. $p$는 $r$가 $a$에 가까울수록 크게, $b$에 가까울수록 작게 설정한다.

이 기법은 round-off 오차가 특정 방향으로 편향(bias)되는 현상을 줄여, 오차가 누적될 때 발생할 수 있는 체계적 오차(systematic error)를 완화하는 효과가 있다. 특히 낮은 정밀도(예: half-precision, bfloat16) 환경에서 딥러닝 훈련 등의 대규모 연산을 수행할 때 확률적 라운딩이 수렴 안정성을 높여준다는 보고가 존재한다. 다만, 현재까지는 하드웨어 및 소프트웨어 지원이 제한적이므로 특수 영역에서 연구 개발 단계에 머무는 경우가 많다.

#### 자동미분(Automatic Differentiation)과 오차 전파

수치해석에서 편미분이나 야코비 행렬, 혹은 헤시안 행렬 등을 구해야 하는 경우가 빈번히 발생한다. 과거에는 수치미분(finite difference)을 사용했지만, 매우 작은 $h$를 쓰면 \*\*소멸 오차(cancellation error)\*\*가 커지고, $h$가 너무 크면 근사 정확도가 떨어지는 등 미세한 조정이 필요했다.

자동미분(AD, Automatic Differentiation)은 연산 그래프 단위로 미분값을 추적하여, 이산적 분차를 쓰지 않고도 오차가 없는 미분을 계산하는 기법이다. 예를 들어, 프로그램 코드 수준에서 변수별 미분을 기계적으로 추적하기 때문에, 테일러 전개나 차분 근사의 ‘절단오차’가 발생하지 않는다. 단순히 반올림오차만 남게 되고, 그나마도 어떤 연산 순서를 취하느냐에 따라 일반 수치 계산과 동일하게 관리할 수 있다.

AD는 역전파(backpropagation)로 잘 알려진 딥러닝에도 쓰이고, 최적화 문제에서 정확한 구배 정보를 얻는 수단으로도 쓰인다. 이때, 미분값에 대한 반올림오차 누적은 일반 계산에서의 round-off 이론과 같으므로, 알고리즘 구현 시 오차 관리가 필요하다.

#### 추가적 고찰

현대 수치해석은 단순히 “근사해가 얼마나 참값에 가깝냐”만 보는 것이 아니라, 다양한 오차 요인이 상호작용하는 복잡한 시스템을 다룬다. 기본적인 절단오차와 반올림오차 이외에도, 문제 설정 단계에서의 모델링 불확실성, 파라미터 추정 과정의 통계적 변동성, 심지어 계층적 알고리즘(멀티그리드, 도메인 분할, 적응적 메쉬 등)에서의 구조적 오차가 모두 겹쳐서 결과값에 영향을 미칠 수 있다.

그럼에도 해답은 오차 요인을 정확히 분류하고, 필요에 따라 더 높은 정밀도나 더 안정적인 알고리즘, 혹은 보수적인 구간 연산 또는 확률적 라운딩 등을 적용해가며 문제를 해결하는 것이다. 실제 적용 분야에서는 사용 가능한 계산 자원과 요구精度, 그리고 시간이 상호 제약 조건을 이루므로, 이 세 가지를 종합적으로 고려해야 한다.

#### 멀티그리드(Multigrid) 기법과 오차 스케일링

수치선형대수학이나 편미분방정식을 다룰 때, 큰 계(system)를 효율적으로 풀기 위해 **멀티그리드 기법**을 사용하는 경우가 많다. 이 기법은 서로 다른 스케일(그리드 혹은 메쉬 간격)을 오가며 오차 성분을 분산시키고, 빠르게 소멸시키도록 설계된다. 예를 들어 잔차(residual)를 큰 스케일에서 보면 효과적인 개선 방향(코스 그리드 보정)이 드러나고, 미세 스케일로 내려오면 마지막 세부 오차를 채워나간다(파인 그리드 스무딩).

멀티그리드 과정에서도 근사해의 정밀도와 정확도는 단계마다 다른 양상을 보인다. 코스 그리드(coarse grid) 단계에서는 상대적으로 큰 절단오차가 발생하지만 연산량이 적기 때문에 전체 알고리즘의 수렴 속도를 높이는 결정적 역할을 한다. 파인 그리드(fine grid) 단계로 갈수록 절단오차는 줄어들지만 round-off 오차가 누적될 가능성이 커질 수 있다. 이 둘이 균형을 이루어, 결과적으로 적은 연산 횟수와 높은 정확도를 동시에 추구할 수 있는 것이다.

멀티그리드 알고리즘이 안정적으로 작동하려면, 각 스케일에서의 오차 이동(transfer) 연산과 보정 과정이 수치적으로 잘 정의되어야 한다. 예컨대, 아주 작은 스케일로 가는 과정에서 잡음 수준의 round-off 오차가 증폭되지 않도록 제어가 필요하다. 마찬가지로 코스 스케일에서의 절단오차가 다음 단계로 고스란히 넘어가면, 파인 스케일 단계에서 오차가 다시 크게 번질 수 있다. 따라서 그리드 전환 시 사용되는 프로롱게이션(prolongation)·제약(restriction) 연산이 알고리즘 안정성에 중요한 영향을 준다.

#### 대규모 병렬 계산과 통신 오차

현대 수치해석은 대규모 HPC(고성능컴퓨팅) 클러스터나 GPU 아키텍처에서 병렬 계산을 수행하는 경우가 많다. 이때 각 노드 혹은 각 프로세서가 나누어 계산한 중간 결과를 주기적으로 교환해야 하는데, 이 통신 과정에서 (물리적 네트워크 지연, 데이터 패킹·언패킹, 가변 정밀도 변환 등으로 인한) 추가적인 오차나 지연이 발생할 수 있다.

병렬환경에서 오차가 누적되는 전형적인 예로는, 전역 합산(global summation)이다. MPI(메시지 패싱 인터페이스) 등을 통해 여러 프로세서가 나누어 계산한 합을 한곳에 모을 때, 합산 순서가 바뀌거나 누락이 생기면 round-off 오차가 달라질 수 있다. 실제로 큰 규모의 부동소수점 덧셈에서는 값이 매우 큰 요소와 매우 작은 요소를 함께 더할 때 앞서 언급한 소멸오차가 발생한다. 병렬 프로그래밍에서는 이러한 합산 순서가 매번 바뀌기 쉽기 때문에, 결과가 실행마다 조금씩 달라지는 현상이 관측될 수 있다.

이를 보완하기 위해, Kahan summation, pairwise summation, 혹은 확장 정밀도(accumulation variable을 double-double 형태로 구성) 같은 기법이 쓰인다. 다만 병렬 병합 과정에서 연산 순서를 완전히 고정하면 병렬 효율이 떨어지므로, 수치 안정성과 계산 성능 사이의 절충을 고려해야 한다.

#### 분산·병렬 환경에서의 정밀도 모니터링

병렬 및 분산 환경에서는 “각 부분 문제에서 얻은 근사해들이 서로 일관된 정밀도를 보이는가?”라는 질문이 중요하다. 큰 도메인을 여러 조각으로 나누어 각각 병렬 계산한 뒤, 경계 조건에 맞춰 해를 이어 붙이거나 적분 영역을 병합할 때, 부분 간 오차가 균등하게 관리되지 않으면 국지적 불연속이나 스파이크(spike)가 생길 수 있다.

이런 현상은 편미분방정식 해석에서 특히 눈에 띈다. 예를 들어 열전달 시뮬레이션에서 한 서브도메인(subdomain)의 계산 결과가 다른 서브도메인의 결과와 맞물리는 지점에서 수치가 튀어 오르는 경우가 있을 수 있다. 이는 각 도메인에서 발생한 round-off 오차, 절단오차, 혹은 그리드 해상도가 달랐기 때문에 생기는 현상이다. 실무적으로는 도메인 경계에서 보정 연산(경계 보정, 인터폴레이션, 필터링 등)을 해주거나, 수렴 단계 후에 일괄적으로 후처리를 거쳐 매끄럽게 만드는 방식이 쓰인다.

#### 자동 검증과 오류 진단 시스템

수치 계산 소프트웨어가 복잡해지면서, 사용자가 직접 모든 수치 안정성 요소를 파악하기 어려운 상황이 빈번하다. 이에 따라, 컴파일러나 런타임 단계에서 자동으로 오차 진단을 수행하거나, 의심스러운 연산에 대해 경고를 출력하는 시스템이 연구되고 있다. 예컨대, 다음과 같은 기능이 가능하다.

연산 결과의 구간 연산이나 확률적 라운딩을 적용해, 특정 시점에 오차가 임계치를 넘었는지 실시간 모니터링. 서브루틴 호출 간 인자로 들어오는 값이 극도로 크거나 작은 경우(overflow, underflow 위험)가 감지되면 경고 메시지 출력. 대수적으로 동등한 연산 식을 서로 다른 순서로 실행해 보고 결과 차이를 측정, 일정 기준 이상이면 “수치적으로 민감한 코드”라고 표시.

이런 기능들은 대규모 코드를 개발할 때, 무심코 지나치기 쉬운 수치 문제를 사전에 포착하는 데 도움을 준다. 아직은 보편적으로 적용된 예가 많지 않지만, 점차 대형 시뮬레이션 소프트웨어나 안전성이 중요한 응용 분야에서 관심이 높아지고 있다.

#### 미래 전망

수치연산 하드웨어는 기존의 단정도·배정도(half, single, double) 부동소수점 말고도, 다양한 조합의 포맷이 등장하고 있다. 특히 AI·머신러닝 분야에서 bfloat16, FP8 등의 저정밀도 포맷이 확대되면서, “정확도 vs. 연산 속도” 간의 트레이드오프가 더욱 역동적으로 변하고 있다. 동시에, 물리 시뮬레이션이나 정밀 계산 분야에서는 한층 높은 정밀도를 위한 솔루션이 요구된다.

결국 근사해의 정밀도와 정확도를 충분히 확보하기 위해서는 하드웨어, 알고리즘, 소프트웨어가 삼위일체로 설계되어야 한다. 예를 들어, 중요한 연산 일부는 높은 정밀도(또는 구간 연산)로 처리하고, 나머지는 상대적으로 빠른 저정밀도 모드로 돌리는 식의 병용이 현실적인 해법으로 떠오른다. 이를 적절히 자동화·최적화해 주는 런타임 또는 컴파일러 기술이 활발히 개발되고 있으며, 향후에는 표준화가 진전될 것으로 예상된다.

따라서 수치해석 입문 단계에서부터 근사해의 정확도, 정밀도, 그리고 각종 오차 기제가 어떻게 맞물리는지를 폭넓게 이해하는 것은 여전히 중요한 가치가 있다. 실제 현장에 적용될 때, “어떤 부분은 근사 오차가 발생해도 괜찮은지, 어떤 부분은 극도로 높은 정밀도가 필요한지”를 제대로 구분해야 하기 때문이다.

#### 통합적 시각

수치해석은 이론과 실무가 밀착된 학문 분야이므로, 근사해에 수반되는 다양한 오차 요인을 면밀하게 살피는 일이 매우 중요하다. 모델 식 자체에서 비롯되는 모델링 오차, 유한차분이나 유한요소 등으로 인한 절단오차, 부동소수점 표현이 초래하는 반올림오차가 서로 더해져 총합적 오차를 구성한다. 이 총합적 오차는 문제 규모가 커지고, 연산 횟수가 늘어나고, 물리적·수학적 복잡성이 확대될수록 제어가 어려워진다.

현대 수치해석에서는 반복법, 적응적 알고리즘, 대규모 병렬화, 불확실성 전파, 최적화, 심플렉틱 적분 등 매우 다양한 방법론이 주류로 발전해왔다. 각각의 방법론은 고유한 관점에서 오차를 바라보고, 이를 효율적으로 줄이거나 일정 수준 이하로 유지하기 위한 전략을 채택한다. 가령 고차 근사기법과 소형 스텝으로 절단오차를 줄이는 대신 반올림오차가 늘어날 수 있고, 저정밀도 부동소수점으로 연산 속도를 극대화하는 대신 안정성이 떨어질 수 있다. 결국 정밀도와 정확도는 문제의 목적, 실제 응용에서 필요한 신뢰도 수준, 계산 자원과 시간 제약, 하드웨어 특성 등을 종합하여 결정될 수밖에 없다.

다른 한편으로, 실제 응용에서 근사해의 “정확성”은 학술적인 관점 외에도 산업적·사회적 신뢰와 직결되는 경우가 많다. 항공우주, 자동차 안전장치, 의학영상, 금융 리스크 분석 등 중요한 영역일수록 오차에 대한 안전율을 크게 설정하고, 다양한 검증·보정 루틴을 둔다. 임의정밀도 연산이나 구간 연산, 혹은 믹스드 프리시전 기법을 도입해 오차를 엄격히 모니터링하면서도 계산 효율을 최대한 유지하려는 시도가 늘어나고 있다.

수치해석 초급 단계에서는 보통 절대 오차와 상대 오차, 단순한 절단오차와 반올림오차 정도만 다룬다. 그러나 실제로는 전방오차와 후방오차, 조건수, 안정성, ill-conditioned 문제 대처, 병렬 환경에서의 통신 오차, 모델링 불확실성까지 폭넓게 고려해야 한다. 근사해의 정밀도와 정확도를 여러 각도에서 관찰하고 개선하는 작업이야말로 수치해석 분야가 발전해온 주요 동력이 되어 왔다.
