C 프로그래밍 입문/부동소수형 데이터: 두 판 사이의 차이

내용 삭제됨 내용 추가됨
Joshuajh (토론 | 기여)
 
Joshuajh (토론 | 기여)
117번째 줄:
</source></div>
 
<div style='border: dashed 1px #ff0000; background: #fff0f0; padding: 7px; margin: 10px 0px 10px 0px;'>'''참고: 부동소수의 오버플로우와 언더플로우'''
float형의 최대값이 3.402823466E+38 라고 위에서 언급 했는데 만약 그 값에 10을 곱하면 어떻게 될 것인가? 라는 의문을 가진 독자가 혹시 있을지 모르겠다. 이런 경우를 overflow라고 하며, 반대의 경우 underflow가 발생한다. 컴파일러에 따라 반응 방식이 다르긴 하겠지만 underflow인 경우에는 일반적으로 0으로 대체한다. overflow의 경우에는 최근의 컴파일러들은 무한대 값을 나타내는 '''inf'''(infinite)상수로 값이 지정되며, 이전의 컴파일러 들은 실행시간 에러를 발생시키며 프로그램을 정지시킨다.
 
무한대를 나타내는 '''inf'''상수는 inf와 -inf 두 가지가 있다.
</div>
 
<div style='border: dashed 1px #ff0000; background: #fff0f0; padding: 7px; margin: 10px 0px 10px 0px;'>'''참고: 반올림 오차(round-off error)'''
먼저 다음 프로그램을 보자, 입력해서 실행하기 전에 출력결과가 무엇이 나올지 예측해 본 후 실행해서 결과를 보자:
#include <stdio.h>
int main (int argc, char *argv[]) {
volatile float a, b;
a = 3402823466.0 + 1.0;
b = a - 3402823466.0;
printf ("%f\n", b);
return 0;
}
 
* 지정자 volatile은 궂이 입력하지 않아도 정상적으로 동작하겠지만, 혹시라도 출력결과가 1.0이 나온 독자는 volatile을 넣고 다시 실행시켜 보기를 바랍니다.<ref>'''volatile'''은 필요없는 코드 이지만 혹시라도 컴파일러가 최적화를 수행하면서 의미 의미 없다고 보여지는 코드를 제거하는 경우를 배제하기 위해, 노파심에서 코드를 끼워 넣었습니다. 개인적으로 알고있는 컴파일러 중 volatile을 넣어야 하는 컴파일러는 없지만 그래도 혹시나 하는 마음에 끼워 넣었습니다.</ref>
 
float 아마 예측한 출력값은 1.0이었겠지만 실제 출력값은 전혀 예측하지 못한 값이 출력되었을 것 이다. 그 이유는 부동소수를 컴퓨터 내부에 표기하기 위해 부동소수의 값을 지수부와 가수부로 나누어 저장하도록 되어있는데, 일반적으로 float 타입은 가수부를 위해 10진수를 기준으로 6자리에서 7자리 정도를 저장할 공간만을 할애하고 나머지는 지수부와 부호를 표시하기 위해 사용된다. 그렇기 때문에 그 한계를 넘어가는 연산을 수행하려고 한 경우 연산결과가 가수부에서 표현 불가능한 값이 되어버리고 만다. 부동소수형의 연산결과가 전혀 예상치 못한 결과를 낳게되는 다른 원인도 있는데, 지수부에 사용될 메모리 공간이 부족한 경우 가수부의 공간 일부를 가져다 쓰는 경우도 있기 때문에 부동소수 연산을 어떻게 구현했느냐에 따라 같은 자리올림 에러에 의한 값이라 해도 다르게 나올 수 있다.
 
실제로 C라는 언어는 정밀한 연산을 위해 만들어진 언어가 아니라 기계 -- 컴퓨터 하드웨어를 가능하면 효율적으로 동작하는 프로그램을 만들기 위해 만들어진 언어이기 때문에 정확한 실수연산을 하고자 한다면 다른 언어 - 예를 들자면 과학기술 계산용으로 만들어진 포트란(Fortran)을 이용해야 정확한 연산 결과를 얻을 수 있다. C에서 포트란이 제공하는 정밀한 실수연산 기능을 사용하고 싶다면 포트란으로 만들어진 함수를 C에서 호출해서 사용하는 방법도 있다. 포트란 함수를 C에서 호출하는 방법을 알고자 하는 사람은 [http://www.yolinux.com/TUTORIALS/LinuxTutorialMixingFortranAndC.html 포트란 함수를 C에서 호출하는 방법]을 참조하기 바란다.
</div>
 
==== 주석 및 참고자료 ====