Josh Coalson
2004-Sep-10 16:45 UTC
[Flac-dev] Fixed: ERROR: mismatch in decoded data, verify FAILED!
> Also, Kai has been kind enough to send me a copy of his file which > has a > problem only on -8, which I'll be looking into soon.After some intense debugging, I found the problem. One block in the file triggered a very rare bug in the LPC coefficient quantizer caused by insufficient floating point precision. There is a snippet to compute the log(base 2) of a number: floor(log(cmax) / M_LN2) It turns out on at least some x86's compiling with gcc-2.91 (at least) the result of floor(log(8.0) / M_LN2) is 2.0 not 3.0. Anyway, I made a fix and also added code to detect and handle similar problems (related to FP accuracy). Josh __________________________________________________ Do You Yahoo!? Get personalized email addresses from Yahoo! Mail http://personal.mail.yahoo.com/
Matt Zimmerman
2004-Sep-10 16:45 UTC
[Flac-dev] Fixed: ERROR: mismatch in decoded data, verify FAILED!
On Mon, Jul 02, 2001 at 09:50:38PM -0700, Josh Coalson wrote:> After some intense debugging, I found the problem. One block in the file > triggered a very rare bug in the LPC coefficient quantizer caused by > insufficient floating point precision. There is a snippet to compute the > log(base 2) of a number: > > floor(log(cmax) / M_LN2) > > It turns out on at least some x86's compiling with gcc-2.91 (at least) the > result of floor(log(8.0) / M_LN2) is 2.0 not 3.0. Anyway, I made a fix and > also added code to detect and handle similar problems (related to FP > accuracy).This appears to be triggered by -ffast-math. mizar:[/tmp] cat log.c #include <math.h> int main() { double x = 8.0; printf("log(x) / M_LN2 = %.40f\n", log(x) / M_LN2); printf("floor(log(x) / M_LN2) = %.40f\n", floor(log(x) / M_LN2)); return 0; } mizar:[/tmp] gcc -o log log.c -lm mizar:[/tmp] ./log log(x) / M_LN2 = 3.0000000000000000000000000000000000000000 floor(log(x) / M_LN2) = 3.0000000000000000000000000000000000000000 mizar:[/tmp] gcc -ffast-math -o log log.c -lm mizar:[/tmp] ./log log(x) / M_LN2 = 2.9999999999999995559107901499373838305473 floor(log(x) / M_LN2) = 2.0000000000000000000000000000000000000000 mizar:[/tmp] This happens for me with both gcc 2.95.4 and 3.0. According to the documentation, this may not even be a bug. -ffast-math allows gcc to violate ANSI/IEEE floating point rules as an optimization, which means that sometimes mathematically incorrect results may be generated. If flac is expecting exact results here, maybe it shouldn't be using -ffast-math. -- - mdz
Josh Coalson
2004-Sep-10 16:45 UTC
[Flac-dev] Fixed: ERROR: mismatch in decoded data, verify FAILED!
> > After some intense debugging, I found the problem. One block in > > the file > > triggered a very rare bug in the LPC coefficient quantizer caused > > by > > insufficient floating point precision. There is a snippet to > > compute the > > log(base 2) of a number: > > > > floor(log(cmax) / M_LN2) > > > > It turns out on at least some x86's compiling with gcc-2.91 (at > > least) the > > result of floor(log(8.0) / M_LN2) is 2.0 not 3.0. Anyway, I made a > > fix and > > also added code to detect and handle similar problems (related to > > FP > > accuracy). > > This appears to be triggered by -ffast-math. > > mizar:[/tmp] cat log.c > #include <math.h> > > int main() { > double x = 8.0; > printf("log(x) / M_LN2 = %.40f\n", log(x) / M_LN2); > printf("floor(log(x) / M_LN2) = %.40f\n", floor(log(x) / M_LN2)); > return 0; > } > mizar:[/tmp] gcc -o log log.c -lm > mizar:[/tmp] ./log > log(x) / M_LN2 = 3.0000000000000000000000000000000000000000 > floor(log(x) / M_LN2) = 3.0000000000000000000000000000000000000000 > mizar:[/tmp] gcc -ffast-math -o log log.c -lm > mizar:[/tmp] ./log > log(x) / M_LN2 = 2.9999999999999995559107901499373838305473 > floor(log(x) / M_LN2) = 2.0000000000000000000000000000000000000000 > mizar:[/tmp] > > This happens for me with both gcc 2.95.4 and 3.0. According to the > documentation, this may not even be a bug. -ffast-math allows gcc to > violate > ANSI/IEEE floating point rules as an optimization, which means that > sometimes > mathematically incorrect results may be generated. If flac is > expecting exact > results here, maybe it shouldn't be using -ffast-math.Wow, you're thorough! I did some more testing with and without this option. It appears that, at least for flac, -ffast-math is actually very slightly slower in addition to being dangerous, so I'll take it out of the gcc CFLAGS. Josh __________________________________________________ Do You Yahoo!? Get personalized email addresses from Yahoo! Mail http://personal.mail.yahoo.com/