[LAU] building a debian system for audio

Jack O'Quin jack.oquin at gmail.com
Wed May 23 17:57:08 EDT 2007


On 5/23/07, Fons Adriaensen <fons at kokkinizita.net> wrote:
> On Wed, May 23, 2007 at 10:33:12PM +0200, Karl Hammar wrote:
> >
> > On Wed, May 23, 2007 at 10:00:38PM +0200, Fons Adriaensen wrote:
> >
> > > I've been chasing a bug for hours this afternoon, and the conclusion
> > > is that apparently g++, under some conditions, is not consistent
> > > in the way it rounds floats to ints in a expression such as
> > >
> > > float  a, b, x;
> > > int    y;
> > >
> > >    y = (int)((x - a) * b + 0.5f);
> > >
> > > I have this calculation twice, in the same source file. In one
> > > case it's within a for loop, in the second case it's just a single
> > > calculation. Both use exactly the same values for a, b, and x, yet
> > > the result is different (by 1). The value before the cast its something
> > > like 115.50424, and that gets rounded up in one case and down in the
> > > other.
> > >
> > > This is with -O3. Same with -O2, -O1, but OK without optimisation, and
> > > also OK if I use -O3 -march=pentium4.
> > >
> > > Is this to be expected, and should I use floorf() to avoid it, or is it
> > > something that should not happen ?
> >
> > It might not be a bug. You are not guaranteed of the same order of
> > evaluation of arithmetic expressions in C. If you want that you have
> > to use FORTRAN or assembler (maybe some other language has it also).
>
> 1. There is absolutely no ambiguity in order of execution of the statement
>    above.
>
>         - subtract a from x
>         - multiply by b
>         - add 0.5
>         - cast to int
>
> 2. In both cases the floating point result was the same. Only the case to int
>    was different.

I know less about this than you do, Fons.  But, I always seem to end up
adding a rint() to statements like that.  Not because I understand exactly
what is going on, but because otherwise GCC gives me warning messages
about casting float to int.

What happens, if you change those lines like this?...

    y = (int) rint((x - a) * b + 0.5f);

Seems like that should give a consistent result (IIUC).
-- 
 joq



More information about the Linux-audio-user mailing list