<div dir="ltr">Hi Alan,<div><br></div><div>Thanks for the idea, these tricks are always useful to know. They don't solve my issue, though, because my goal isn't just optimization.</div><div><br></div><div>The thing is, I already have closed classes that do "<span style="font-size:12.8px">if (fval >= fminval && fval <= fmaxval)</span><span style="font-size:12.8px">" where all variables are of type "float". My problem is, that I have a range (minval, maxval) in double-precision, and I have to compute (fminval, fminval) in single precision to provide to the existing code. As described above, a naive typecast gives the wrong answer in edge cases, which is why </span><span style="font-size:12.8px">fminval = NearestFloatNotGreaterThan(</span><wbr style="font-size:12.8px"><span style="font-size:12.8px">minval) and </span><span style="font-size:12.8px">fmaxval = NearestFloatNotLessThan(</span><wbr style="font-size:12.8px"><span style="font-size:12.8px">maxval) are necessary.</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Cheers,</span></div><div><span style="font-size:12.8px"> - David</span></div><div><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jun 16, 2017 at 3:28 PM, Scott, W Alan <span dir="ltr"><<a href="mailto:wascott@sandia.gov" target="_blank">wascott@sandia.gov</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div lang="EN-US">
<div class="gmail-m_4964885467435391456WordSection1">
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">Haven’t seen a great reply, and this was a while ago, but here goes. This is also all theoretical, from days 20 years ago when I worked on OpenGL drivers.
<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">How about the following:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">test = (minval – static_cast<double>fval) & (static_cast<double>fval – maxval)<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">Now, test will be positive if your case should pass, negative if not. I’m sure I missed some casts above, but you can see what I am doing. By And’ing the positive bit on
the two floats, you see if result is positive. So, either<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">if(test >= 0)<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"> succeed;<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">else<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"> not so much;<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">Or, if your hardware is faster in integer space (and dirty),<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">if (<unsigned double>test & 0x800000000k)<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">I suspect this whole test should run in under 10 clocks...<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">Be sure to test with different compilers, and especially optimized.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">Alan<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<div style="border-top:none;border-right:none;border-bottom:none;border-left:1.5pt solid blue;padding:0in 0in 0in 4pt">
<div>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(225,225,225);padding:3pt 0in 0in">
<p class="MsoNormal"><b><span style="font-size:11pt;font-family:Calibri,sans-serif">From:</span></b><span style="font-size:11pt;font-family:Calibri,sans-serif"> vtk-developers [mailto:<a href="mailto:vtk-developers-bounces@vtk.org" target="_blank">vtk-developers-<wbr>bounces@vtk.org</a>]
<b>On Behalf Of </b>David Gobbi<br>
<b>Sent:</b> Monday, June 12, 2017 12:16 PM<br>
<b>To:</b> VTK Developers <<a href="mailto:vtk-developers@vtk.org" target="_blank">vtk-developers@vtk.org</a>><br>
<b>Subject:</b> [EXTERNAL] [vtk-developers] Comparing doubles with floats: precision issues<u></u><u></u></span></p>
</div>
</div><div><div class="gmail-h5">
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">Hi All,<u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">This is one of those picky math questions that deals with numerical precision. Let's say that one has a data set with scalar type "float", and wants to select values within a range (minval, maxval) where minval, maxval are of type "double":<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> if (fval >= minval && fval <= maxval) { ... }<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Now let's say you don't want "fval" to be converted to double, because floats are faster than doubles on your hardware:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> float fminval = static_cast<float>(minval);<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> float fmaxval = static_cast<float>(maxval);<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> ...<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> if (fval >= fminval && fval <= fmaxval) { ... }<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Unfortunately, there are some cases where fval <= fmaxval even though fval > maxval. Reducing the precision of the range has invalidated the check. In order to fix things, you must choose fminval to be the value closest to but not more
than minval, and choose fmaxval to be the value closest to but not less than maxval.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> float fminval = NearestFloatNotGreaterThan(<wbr>minval);<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> float fmaxval = NearestFloatNotLessThan(<wbr>maxval);<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">With these, (fval >= fminval && fval <= fmaxval) gives the same result as (fval >= minval && val <= fmaxval) and all is right with the world.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">So my question is, have any other devs created a solution for this issue, either for VTK or for related code? I'm considering a solution based on the C++11 function std::nextafter(), as described on this stackoverflow page: <a href="https://stackoverflow.com/questions/15294046/round-a-double-to-the-closest-and-greater-float" target="_blank">https://stackoverflow.<wbr>com/questions/15294046/round-<wbr>a-double-to-the-closest-and-<wbr>greater-float</a><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> - David</p></div><div><p class="MsoNormal"><u></u></p></div></div></div></div></div></div></div></blockquote></div></div></div></div>