정수에는 자리수의 유한 함으로 수의 넘침 현상이 일어나고 , 실수에는 정확한 수를 표현할 수가 없는 경우가 있습니다. 이 부분에 초점을 두겠습니다.

1.IEEE 754 단정도 부동소수(float) 표현 법

float 형 변수는 다음과 같은 틀의 형태로 저장된다.

예를 들어 10 진수는 12.5 는

*지수부에는 bias 라는 것을 적용해서 지수값에 127 을 더한 후 지수부에 기억한다.

----확인

#include <stdio.h>

int main()
{
   float a; 
   a = 12.5;
   printf("%x",a);
}
그런데 %x 는 실수형에서는 작동이 되지 않는가 제대로 된 결과를 볼수가 없어 다음과 같은 코드로 다시 시도.
#include <stdio.h>

int main()
{
   float *a;
   a = new float;
   *a = 12.5;

   printf("%x",*(int*)a);
}
위에서 설명한 대로 출력되는 것을 확인 함.(vc 와 gcc 동일)
41480000

2. 실수에서 round off 오류가 발생하는 이유

만약 소수부의 자리수를 4 비트로 사용한다면 소수부가 나타낼 수 있는 것은 0.0 과 0.0625 사이에 있는 수는 이 둘 중 하나로 표현될 수 밖에 없습니다. 이 0.0625 를 Epsilon 오차라 합니다.

그래서 가능하면 소수부가 크면 클수록 더 정확하게 표현할 수가 있으니 정확한 연산을 위해서는 소수부를 3 바이트 쓰는 float 보다는 소수부를 3 + 4 = 7 바이트 사용하는 double 형을 사용하는게 안전합니다. 물론 double 형도 Epsilon 오차가 발생하지만 float 보다는 더 작습니다.

3. 실수 비교 방법

일단 , 두 실수를 비교할 때는 컴퓨터내에서 실수를 표현하는데 유한한 자리와 수체계로 인하여 어느정도의 오차 범위내에서 수를 비교하는게 안전할 듯 합니다.

두 실수 a,b 가 있다면
if ( a == b ) ..
보다는

if ( fabs( a - b) < DBL_EPSILON ) ....

fabs 두 실수의 절대값 구하는 함수이고 두 수의 차가 double 형의 오차의 한계 DBL_EPSION 보다 작으면으로 가는게 안전한 코딩이 될 것 같습니다. 여기에서 fabs 는 math.h 에 DBL_EPSION 은 float.h 에 정의가 되어 있습니다.

#include <math.h>
#include <float.h>
int main()  
{  
     double a,b;

     ...
     if( fabs( a - b)  < DBL_EPSILON ){ //  a 와 b 가 같으면 
        ....
     }  
}
출처:dovelet

[질/답]
[홈으로]  [뒤 로]
[푼 후(0)]