VC6++의 컴파일 옵티마이징 옵션중에 /Op (Improve Float Consistency)를 켜보시면 원하시는 결과를 얻을 수 있을 겁니다.
알고 있어도 자주 알 수 없는 버그의 원인이 되곤 하는 문제죠.
위와 같은 옵션은 속도와 실행 파일 크기가 문제가 되기 때문에 아래와 같이 오차 한계를 두고 처리 하는 방법이 제일 속편합니다. (물론 float로 ==, != 오퍼레이터의 결과가 안정적으로 나오길 바랄 때만 사용 하시면 될듯...)
Code: Select all
#include <math.h>
#include <stdio.h>
#define EPSILON 0.0001 // Define your own tolerance
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))
int main(int argc, char* argv[])
{
float a = sqrtf( 10 );
float b = sqrtf( 10 );
if ( a == sqrtf(10) )
printf( "same a==sqrtf(10)\n" );
if ( a == b )
printf( "same a==b\n" );
if ( FLOAT_EQ(a, sqrtf(10)) )
printf("same FLOAT_EQ(a, sqrtf(10))\n");
return 0;
}
자세한 내용은 MSDN의 "색인(N)"메뉴에서 "/Op"를 쳐보시면 아주 친절하게 잘 나와 있습니다. (물론 영문으로 나와 있기 때문에 전부 읽어 보고 싶지는 않더군요.^^;)
MSDN에서 몇줄 가져와 보면...(해석은 알아서...한 마디로 "별로 좋지 않으니 피하자"라고 이해 하고 있습니다.)
The Improve Float Consistency (/Op[–]) option improves the consistency of floating-point tests for equality and inequality by disabling optimizations that could change the precision of floating-point calculations. (To find this option in the development environment, click Settings on the Project menu. Then click the C/C++ tab, and click Optimizations in the Category box. Under Optimizations, click Customize.)
By default, the compiler uses the coprocessor’s 80-bit registers to hold the intermediate results of floating-point calculations. This increases program speed and decreases program size. However, because the calculation involves floating-point data types that are represented in memory by less than 80 bits, carrying the extra bits of precision (80 bits minus the number of bits in a smaller floating-point type) through a lengthy calculation can produce inconsistent results.
With /Op, the compiler loads data from memory prior to each floating-point operation and, if assignment occurs, writes the results back to memory upon completion. Loading the data prior to each operation guarantees that the data does not retain any significance greater than the capacity of its type.