fcvt() should write into its buffer the digits of the supplied double, without sign or decimal points. A bug causes fcvt() to misinterpret some doubles as being negative, and in the confusion makes a mess of its output. Will attach sample code. Looking at the glibc-2.3.1 source, there's nothing obvious! It looks as though signbit() is sometimes returning the wrong result in misc/efgcvt_r.c:fcvt_r(). However signbit() called in the sample code produces the expected results. This bug is causing cdrecord,mkisofs and friends in cdrtools using libschily to present bogus %ages in their output, as libschily provides its own fprintf() which uses fcvt() to print floating point numbers. From /etc/make.conf: CHOST="i686-pc-linux-gnu" CFLAGS="-march=pentium4 -O3 -pipe"
what happens if you compile with -march=pentium3 ? from all accounts, the "-march=pentium4" optimisation causes all sorts of brokenness in all sorts of places.
Created attachment 6528 [details] Test code demonstrating fcvt() bug Compile with gcc -std=gnu99
IIRC, glibc-2.3.1 is compiled with all the CFLAGS stripped of anything offensive like -march=pentium4 ... I could rebuild glibc without that in the make.conf, but it's a lot of trouble :) 'strip-flags' in the glibc-2.3.1 ebuild does strip out -march=pentium4, doesn't it? The sample code is compiled without optimizations of any sort though.
Just learnt that strip-flags() left -march alone ... time for some rebuilding! Hopefully it's just a pentium4 optimization bug in GCC. Will update with results.
Ayup! It was march=pentium4 giving me grief. Thanks for the tip! Rebuilt glibc with march=pentium3 -O3, and now everything is happy again.
Ditto, got a pentium4 myself, but compile with -march=pentium3 -O2 -pipe until the gcc guys get the pentium4 optimizations sorted.