[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