Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I check whether two numbers are within "x" significant figures of the precision limits of the floating point type?
    primarykey
    data
    text
    <p>So suppose we have a float type XType in which we have two numbers:</p> <pre><code>XType const a = 1.2345 XType const b = 1.2300 </code></pre> <p>Then I want a function IsClose(XType const f1,XType const f2,unsigned const truncated_figures) such that</p> <pre><code>// the numbers are equal if the last two figures are ignored (1.23 == 1.23) IsClose&lt;XType&gt;(a,b,2) == true // the numbers are not equal if only the last is ignored (1.234 != 1.230) IsClose&lt;XType&gt;(a,b,1) == false </code></pre> <p>So far I have this ugly mess, but I'm yet to convince myself it's correct:</p> <pre><code>// check if two floating point numbers are close to within "figures_tolerance" figures of precision for the applicable type template &lt;typename FloatType&gt; bool const IsClose(FloatType const f1, FloatType const f2, unsigned const figures_tolerance) { FloatType const tolerance_exponent = std::pow(10.0,figures_tolerance); FloatType const tolerance = std::pow(tolerance_exponent,std::log10(f1)) * std::numeric_limits&lt;FloatType&gt;::epsilon() ; return std::abs(f1 - f2) &lt; tolerance; } </code></pre> <p>My reasoning is that the tolerance should be the epsilon raised to the order of magnitude that the number exceeds or subseeds 1.0 (the significant figures for which the epsilon is based). Does this make sense? Is there a better, more reliable way?</p> <p>EDIT: My solution using the template function is below (it is based on user763305's answer below)</p> <pre><code>// check if two floating point numbers are within the last n digits of precision for the // largest of the two numbers being compared. template &lt;typename FloatType&gt; bool const IsWithinPrecision(FloatType const f1, FloatType const f2, unsigned const n = 1U) { FloatType const f_ref = std::max(std::abs(f1), std::abs(f2)); FloatType const distance = std::abs(f1 - f2); FloatType const e = std::numeric_limits&lt;FloatType&gt;::epsilon(); return distance &lt; std::pow((FloatType) 10.0, (FloatType) n) * e * f_ref; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload