<div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif">Even with double precision numbers stored in those tables, you're still restricting your input to the 254 exponent values and 10 bits of mantissa.</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">The rough outline of the algorithm hinges on the idea that sqrt(a*b) = sqrt(a) * sqrt(b). So, since floating point is represented exponent*mantissa, you can get sqrt(e*m) by doing sqrt(e)*sqrt(m). That means if you can pre-compute all possible sqrt(e) except NaNs, infs, and denormals, and enough mantissa values to whatever significant bits you want, you can get really efficient. The reason to precompute the reciprocal first is because you save the divide in the perform function. Instead, you can rely on f*(1/sqrt(f)) = sqrt(f), so it's a simple multiply by the float you already have.</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">The rest of it is just bit paperwork. All the << 23 you see are to get to the exponent bits. The mantissa table holds rsqrt values for 1.0 + intervals of 1./1024. (that initial 1.0 is implied in normalized float representation).</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">So basically, you're accepting double-precision values for inputs truncated to 18 bits of precision. One problem is that you'll get very bad values for very high input exponents because you're bashing everything to single-precision exponent range. Might not be the worst thing, but something to consider.<br><br>Matt</div><div class="gmail_default"><div class="gmail_default"><font face="verdana, sans-serif"><br></font></div><div class="gmail_default"><font face="verdana, sans-serif"><br></font></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 6, 2018 at 11:34 PM, Jonathan Wilkes <span dir="ltr"><<a href="mailto:jon.w.wilkes@gmail.com" target="_blank">jon.w.wilkes@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi list,<br>
<br>
Looking at a double precision patch here:<br>
<br>
<a href="https://git.purrdata.net/jwilkes/purr-data/merge_requests/224" rel="noreferrer" target="_blank">https://git.purrdata.net/<wbr>jwilkes/purr-data/merge_<wbr>requests/224</a><br>
<br>
And looking at these declarations/definitions from d_math.c:<br>
<br>
static float rsqrt_exptab[DUMTAB1SIZE], rsqrt_mantissatab[DUMTAB2SIZE]<wbr>;<br>
<br>
So... what happens if we just change "float" to "t_float" here?<br>
<br>
At a glance it seems like we can still cast back to "float" to<br>
derive the index in sigsqrt_perform. Then we grab the<br>
t_float from that index and do the remaining multiplications<br>
at double precision instead of single precision.<br>
<br>
On the other hand, that would be 8 double-precision float<br>
operations per sample.<br>
<br>
Anyhow, as it is this algorithm appears to compute the<br>
same values for both single- and double-precision versions<br>
of Purr Data.<br>
<br>
I'm not sure how to judge the importance of realtime<br>
efficiency vs. whatever precision expectations someone<br>
has when running double-precision Purr Data. (I also don't<br>
completely understand the algorithm.)<br>
<br>
Any thoughts?<br>
______________________________<wbr>_________________<br>
L2Ork-dev mailing list<br>
<a href="mailto:L2Ork-dev@disis.music.vt.edu">L2Ork-dev@disis.music.vt.edu</a><br>
<a href="https://disis.music.vt.edu/listinfo/l2ork-dev" rel="noreferrer" target="_blank">https://disis.music.vt.edu/<wbr>listinfo/l2ork-dev</a></blockquote></div><br></div>