Created attachment 446074 [details] gcc -m32 -ansi test.c Version-Release number of selected component (if applicable): gcc-4.5.1-3.fc14 How reproducible: 100% Steps to Reproduce: 1. gcc -m32 -ansi test.c 2. ./a.out where test.c is #include <stdio.h> int main(void) { double d=0.1; if(d!=0.1) printf("unexpected!\n"); return 0; } Actual results: "unexpected!" Expected results: nothing Additional info: caught by icu make check, so this didn't happen earlier in the F-14 cycle without "-ansi" this behaves as expected. Seems odd that -ansi has an effect on this.
I'm not sure about the C/C++ standards, but it is usually a bad idea to strictly compare two floats or doubles. It is recommended to compare that two floats/doubles are roughly equal, with a given accuracy of epsilon (e.g., 1e-3). That statement comes from years of experience with several major OLTP applications on different Unices (HP-UX, SunOS, Linux) running on different hardware platforms in production. Sometimes, a given application, where we compared two floats, runned two or three years in production with 10tps (transactions per second) 24x7, without any problem. Then, suddenly, nobody could explain why, but the application started to fail: the floats became no longer equal (and sometimes, not not equal at the same time!). Hence, we have implemented the epsilon trick everywhere we needed to compare two floats/doubles. And we have been able to sleep quietly ever since... That's just my $0.02
i?86-linux is a FLT_EVAL_METHOD 2 target (because of the insane i?87 hw), and that requires that for strict standard conformance all operations and constants are supposed to be evaluated in precision of long double. d is a double variable, so the constant needs to be casted to double precision, so it is evaluated as double d = 0.1; if ((long double) d != 0.1L) and those constants are different. If you write it as if(d!=(double)0.1), it will be equal. GCC 4.5 implement this standard conformant mode. There is the -fexcess-precision={fast,standard} option to select behavior, with standard being the default for -std={c89,c9*,iso*} and fast otherwise. Of course for FLT_EVAL_METHOD 0 targets like x86-64 this doesn't make difference. What Denis wrote above is a reasonable recommendation in any case.
Fixed in ICU upstream http://bugs.icu-project.org/trac/ticket/7932 ( Should ICU be an available external bug type here?)