Subj : Re: Serious Problem with precision or if statement To : borland.public.cpp.borlandcpp From : " Bruce Salzman" Date : Wed Aug 13 2003 03:07 pm > #include > > int main() { > > int Phase = 3; > > if( Phase/3.0 == 1.0 ) > printf("equal"); > else > printf("not equal"); > > return 1; > } > ----------------------- > > Now we would expect "equal" to be printed, but to my > (everyone's) surprise, "not equal" is printed. > IEEE floating point cannot represent certain numbers exactly. 1/3 is one of them. Testing floating point numbers for equality is not recommended. Usually one uses an "epsilon test" to determine if the numbers are "close enough" to be declared equal. > An even more extraordinary thing occurs when tracing the program. > The expression ( Phase/3.0 == 1.0 ) evaluates to TRUE. However, > the else(FALSE) branch is taken printing "not equal"! How did you determine that the expression evaluates to true? When I step through the assembly code in the debugger, (after the SAHF instruction) I see the zero flag is clear (Z = 0) and the carry flag is set (C = 1). The following JNE is (correcty) taken. > > I have tried several modifications to the if statement > to no avail. > > if( (double)Phase/3 == 1.0 ) > if( Phase/3.0 == (double) 1 ) > Again, testing for equality is not going to do what you might expect. > It is worthwhile to note that > if( Phase/3 == 1 ) does return the correct answer. > Integer division this time. 3 / 3 = 1 > Assigning the value (Phase/3.0) to an intermediate double x > and then checking if( x == 1.0 ) also works. > > If anyone has time or wants some amusement, run my program. > I am using Borland C++ 5.02 on an Intel Pentium III with Windows > XP. I get the same results with a AMD Duron with Windows 98. > Not surprised. > Under LINUX compiled for i586, compiling and running my program > with gcc returns "equal", the correct answer. Don't know gcc, so I can't say what it's floating point math is up to. HTH, Bruce .