Re: [linux-audio-dev] Traps in floating point code

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: Re: [linux-audio-dev] Traps in floating point code
From: Pete Bessman (ninjadroid_AT_gazuga.net)
Date: Wed Jun 30 2004 - 17:43:40 EEST


At Mon, 28 Jun 2004 19:56:50 +1000,
Erik de Castro Lopo wrote:
>
>
> People who play around with floating point code (especially on x86)
> quickly learn about the evils of comparing the equality of one floating
> point value with another.

I got my first lesson just a couple of days ago, in fact. Gave me all
the encouragement I needed to learn assembler.

On a similar note, I remember when I was just starting out, and was so
new to C that I didn't even know sprintf existed, I wrote a naive
float-to-string conversion routine. I was encountering the
*strangest* problems; certain digits would come out either one step
higher or lower than they should have.

Turns out this was a number theory problem (didn't know what that was
at the time, still not sure I do). My algorithm would divide the
input number by 10 repeatedly until the results was less than 10. It
would then convert the integer value to a character, subtract the
integer value from the float value, then multiply the float value by
10 and repeat until done.

Now, if computers operated on a base 10 system this would've been fine
and dandy, since every digit could be cleanly represented when divided
by 10. However, the only decimal fraction you can represent cleanly
in binary is 0.5 (comes out as 0.1 in binary). Everything else
results in a repeating fraction, and good luck figuring out what
you'll wind up with when you multiply that by 10 to make it an
integer.

There is *many* a slip betwixt the cusp and the lip.

> double fractional = 0.0, increment = 0.1;
> int integer = 0;
>
> for (;;)
> {
> /* Bunch of other code. */
>
> fractional += increment ;
> integer += lrint (floor (fractional));
> fractional -= floor (fractional);
> }

I don't understand this lrint (floor ()) stuff. floor() returns a
truncated integer value, so what's the point of calling lrint() on
that? Why wouldn't integer += fractional suffice? A corollary of
this is that I don't understand the problem...

> The fix in this case was this:

...and a corollary of the corollary is that I don't understand the
fix :-\

-Pete

www.gazuga.net


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Wed Jun 30 2004 - 17:34:44 EEST