[Flac-dev] Fixed: ERROR: mismatch in decoded data, verify FAILED!
Frank Klemm
pfk at fuchs.offl.uni-jena.de
Tue Jul 17 17:21:45 PDT 2001
On Tue, Jul 17, 2001 at 12:46:13PM -0700, Josh Coalson wrote:
> > 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.
>
I would never use such a function to evaluate the needed number of bits.
Never. Also with no '-ffast-math' it is pure luck that this so often works.
And also it is very slow due to a misconception in C and in the Intel FPU
rounding method.
int bits_of_a_value ( TYPE x );
1st question: basic type of TYPE? (int, long, flaot, double)
2nd question: maximum possible range (<2^8, <2^16, <2^24, <2^32)?
3rd question: return value for x=0 ?
A always working and fast solution is:
int bits_of_a_value ( int value )
{
static const signed char helper_tab [256] = {
-1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4, ... // table depends on your exact needs (count of bits or no of MSB etc.)
... ,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
};
if ( value >= 256 ) {
if ( value >= 65536 ) {
if ( value >= 16777216 ) {
return 24 + helper_tab [value >> 24];
}
return 16 + helper_tab [value >> 16];
}
return 8 + helper_tab [value >> 8];
}
return helper_tab [value];
}
Compare performance !!!
Stuff like
inline int whichpow2_2 ( unsigned long n )
{
int c = 0;
if ( n & 0xAAAAAAAA ) c += 1;
if ( n & 0xCCCCCCCC ) c += 2;
if ( n & 0xF0F0F0F0 ) c += 4;
if ( n & 0xFF00FF00 ) c += 8;
if ( n & 0xFFFF0000 ) c += 16; /* auch if (n > 0xFFFF) möglich */
return c;
}
also works, but is slower.
--
Frank Klemm
More information about the Flac-dev
mailing list