메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

C, C++, C#으로 알아본 머신 입실론 알고리즘

한빛미디어

|

2001-09-12

|

by HANBIT

11,699

By 한동훈(traxacun@unitel.co.kr) 머신 입실론은 컴퓨터가 이해할 수 있는 가장 작은 숫자 단위를 말한다. 알다시피 컴퓨터는 실수를 이진수의 형태로 저장한다. 때문에 1/3과 같은 숫자를 저장하는 것은 불가능하다. 하지만 대부분의 경우에 여러분은 무한히 긴 0.333333333333.... 을 볼 수 있었을 것이다. 그러나 그 마지막 값은 일반적으로 3이 아니라... 2나 4가 된다. 이와 같이 컴퓨터가 다룰 수 있는 가장 작은 수, 즉 임계값을 머신 입실론이라한다. 다른 말로는 1보다 큰 가장 작은 숫자를 머신 입실론이라 한다. 그래서 종종 머신 입실론 값은 정확한 계산이 필요한 회계 분야나 공학 분야에서 중요하다. 그래서 여기서는 알고리즘으로 머신 입실론 값을 구해보고, C++과 C# 언어에서 지원하는 머신 입실론 관련 함수를 알아본다. 작업환경:
  • C Compiler : Microsoft 32bit C/C++ Optimization Compiler version 13.00.9254(80x86버전)
  • C# Compiler : Microsoft Visual C# Compiler Version 7.00.9254[ CLR Version v 1.0.2914]

이름: machine_eps.cs

// machine epsilion

#include 	// 필요한 함수에 대한 헤더 파일 선언

int main()		// main 함수 선언.
{
  float ex, g = 1, eps;	// float(단정도 실수) 변수 ex, g, eps 선언

  do			// do while loop 문 시작
  {
    g = g / 2;		// g의 값을 2로 나눈후에 g에 저장
    ex = g * 0.98 - 1;	// 계산된 g 값에 0.98을 곱하고 1을 뺀다.
    ex = ex - 1;	// 계산된 ex에서 1을 뺀다.

    printf("g = %15.8e    ex = %15.8e₩n", g, ex); 
    // 형식 지정자 %15.8e를 사용해서 e 지수 타입으로 표시하며 
    // 각 자리수는 15자리와 8자리로 표현한다.

    if ( ex > 0 ) eps = ex;  // ex가 0보다 크다면 eps에 ex값을 저장한다.

  }
  while ( ex > 0 );	
  // ex가 0보다 크다면 계속 반복한다.
  // Ex의 값이 0이거나 0보다 작으면 루프를 종료한다.
 
  printf("₩n Machine epsilon = %16.8e₩n₩n", eps);
  // machine epsilon 값을 출력한다.
  return 0;
  // main 함수 반환 타입을 int로 썼으므로 성공적인 숫자 0을 반환한다.
}
machine_eps.exe의 실행결과 E:₩works₩c>machine_eps.exe g = 5.00000000e-001 ex = -1.51000000e+000 Machine epsilon = 5.60519386e-045 설명: 정확한 머신 입실론 값을 측정할 수 없다. 실제로 현재 쓰이고 있는 CPU에서 단정도의 머신 입실론 값은 1.401298E-45다. C#에서는 머신 입실론을 알고리즘을 통하지 않고, 프로퍼티를 통해서 바로 알 수 있다. Float는 단정도 실수이며 4 바이트를 사용한다. 마찬가지로 C#에서는 System.Single 클래스에 대한 별칭으로 float 데이터 타입을 사용하며 4 바이트를 사용하는 단정도 실수이다. 이 소스에는 치명적인 단점이 있는데, integer 타입의 single 타입으로 암시적인 캐스팅이 이뤄지고 있어서 정확한 계산이 이뤄지지 않았다.

이름: machine_eps2.cs

using System;

public class MachineEps
{
  public static void Main(string [] args)
  {
     Console.WriteLine(System.Single.Epsilon);
  }
}
실행결과: 1.401298E-45 단정도 실수에 대한 C# 언어에서의 머신 입실론 값을 알 수 있다. C++ 언어에서의 입실론 값은 다음과 같다.

이름: machine_eps3.cpp

// compile with: /EHsc
#include 
#include 

using namespace std;

int main( )
{
   cout << "float objects is: " 
        << numeric_limits::epsilon( ) 
        << endl;
   cout << "for double objects is: " 
        << numeric_limits::epsilon( ) 
        << endl;
   cout << "long double objects is: " 
        << numeric_limits::epsilon( ) 
        << endl;
   return 0;
}

위 코드의 컴파일은 다음과 같이 해야한다. Cl /EHsc machine_eps3.cpp /EHsc는 /EHs와 /EHc를 뜻한다. EHs는 동기 예외 처리 모델을 사용한다는 것을 뜻하며, EHc는 C++의 예외 처리 모델을 사용하지 않는 다는 것을 뜻한다. 이와 같이 하지 않으면 컴파일은 되지만 예외 처리가 되지 않은 코드에서 예외가 발생하기에 에러를 만날 것이다. 실행결과: float objects is: 1.19209e-007 for double objects is: 2.22045e-016 long double objects is: 2.22045e-016 이상으로 C, C++, C#에서 머신 입실론에 대해서 살펴보았다. C++와 같은 전통적인 언어는 탄생된지 오래되었기 때문에 언어가 탄생되는 시점의 하드웨어를 반영하고 있기에 현대 프로그래밍 언어에 비하면 같이 정확하지 못하다. C#과 같은 언어에서는 자체적으로 머신 입실론 값을 알 수 있는 프로퍼티를 제공하고 있으며, 별도의 데이터 타입에 대한 입실론 값을 구할 수 있는 epsilon 메소드를 제공한다. 또한 벡터 연산을 간단히 구현할 수 있고, 복소수 연산을 손쉽게 할 수 있으며, System.Decimal과 같은 12 바이트의 데이터 타입을 지원하여 보다 정확한 실수 값을 지원한다.
TAG :
댓글 입력
자료실