mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-03 21:40:52 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			414 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			414 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<html>
 | 
						|
<head>
 | 
						|
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
 | 
						|
<title>Floating-point Comparison</title>
 | 
						|
<link rel="stylesheet" href="../math.css" type="text/css">
 | 
						|
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
 | 
						|
<link rel="home" href="../index.html" title="Math Toolkit 2.5.1">
 | 
						|
<link rel="up" href="../utils.html" title="Chapter 2. Floating Point Utilities">
 | 
						|
<link rel="prev" href="next_float/ulp.html" title="Obtaining the Size of a Unit In the Last Place - ULP">
 | 
						|
<link rel="next" href="../cstdfloat.html" title="Chapter 3. Specified-width floating-point typedefs">
 | 
						|
</head>
 | 
						|
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
 | 
						|
<table cellpadding="2" width="100%"><tr>
 | 
						|
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
 | 
						|
<td align="center"><a href="../../../../../index.html">Home</a></td>
 | 
						|
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
 | 
						|
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
 | 
						|
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
 | 
						|
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
 | 
						|
</tr></table>
 | 
						|
<hr>
 | 
						|
<div class="spirit-nav">
 | 
						|
<a accesskey="p" href="next_float/ulp.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../utils.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../cstdfloat.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
 | 
						|
</div>
 | 
						|
<div class="section">
 | 
						|
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
 | 
						|
<a name="math_toolkit.float_comparison"></a><a class="link" href="float_comparison.html" title="Floating-point Comparison">Floating-point Comparison</a>
 | 
						|
</h2></div></div></div>
 | 
						|
<p>
 | 
						|
      Comparison of floating-point values has always been a source of endless difficulty
 | 
						|
      and confusion.
 | 
						|
    </p>
 | 
						|
<p>
 | 
						|
      Unlike integral values that are exact, all floating-point operations will potentially
 | 
						|
      produce an inexact result that will be rounded to the nearest available binary
 | 
						|
      representation. Even apparently inocuous operations such as assigning 0.1 to
 | 
						|
      a double produces an inexact result (as this decimal number has no exact binary
 | 
						|
      representation).
 | 
						|
    </p>
 | 
						|
<p>
 | 
						|
      Floating-point computations also involve rounding so that some 'computational
 | 
						|
      noise' is added, and hence results are also not exact (although repeatable,
 | 
						|
      at least under identical platforms and compile options).
 | 
						|
    </p>
 | 
						|
<p>
 | 
						|
      Sadly, this conflicts with the expectation of most users, as many articles
 | 
						|
      and innumerable cries for help show all too well.
 | 
						|
    </p>
 | 
						|
<p>
 | 
						|
      Some background reading is:
 | 
						|
    </p>
 | 
						|
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
 | 
						|
<li class="listitem">
 | 
						|
          Knuth D.E. The art of computer programming, vol II, section 4.2, especially
 | 
						|
          Floating-Point Comparison 4.2.2, pages 198-220.
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          <a href="http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html" target="_top">David
 | 
						|
          Goldberg, "What Every Computer Scientist Should Know About Floating-Point
 | 
						|
          Arithmetic"</a>
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          <a href="http://adtmag.com/articles/2000/03/16/comparing-floatshow-to-determine-if-floating-quantities-are-close-enough-once-a-tolerance-has-been-r.aspx" target="_top">Alberto
 | 
						|
          Squassabia, Comparing floats listing</a>
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          <a href="https://code.google.com/p/googletest/wiki/AdvancedGuide#Floating-Point_Comparison" target="_top">Google
 | 
						|
          Floating-Point_Comparison guide</a>
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          <a href="../../../../../libs/test/doc/html/boost_test/users_guide/testing_tools/testing_floating_points.html" target="_top">Boost.Test
 | 
						|
          Floating-Point_Comparison</a>
 | 
						|
        </li>
 | 
						|
</ul></div>
 | 
						|
<p>
 | 
						|
      Boost provides a number of ways to compare floating-point values to see if
 | 
						|
      they are tolerably close enough to each other, but first we must decide what
 | 
						|
      kind of comparison we require:
 | 
						|
    </p>
 | 
						|
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
 | 
						|
<li class="listitem">
 | 
						|
          Absolute difference/error: the absolute difference between two values
 | 
						|
          <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span> is simply <code class="computeroutput"><span class="identifier">fabs</span><span class="special">(</span><span class="identifier">a</span><span class="special">-</span><span class="identifier">b</span><span class="special">)</span></code>. This is the only meaningful comparison
 | 
						|
          to make if we know that the result may have cancellation error (see below).
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          The edit distance between the two values: i.e. how many (binary) floating-point
 | 
						|
          values are between two values <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span>?
 | 
						|
          This is provided by the function <a href="../../../../../libs/math/doc/html/math_toolkit/next_float/float_distance.html" target="_top">Boost.Math
 | 
						|
          float_distance</a>, but is probably only useful when you know that
 | 
						|
          the distance should be very small. This function is somewhat difficult
 | 
						|
          to compute, and doesn't scale to values that are very far apart. In other
 | 
						|
          words, use with care.
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          The relative distance/error between two values. This is quick and easy
 | 
						|
          to compute, and is generally the method of choice when checking that your
 | 
						|
          results are "tolerably close" to one another. However, it is
 | 
						|
          not as exact as the edit distance when dealing with small differences,
 | 
						|
          and due to the way floating-point values are encoded can "wobble"
 | 
						|
          by a factor of 2 compared to the "true" edit distance. This is
 | 
						|
          the method documented below: if <code class="computeroutput"><span class="identifier">float_distance</span></code>
 | 
						|
          is a surgeon's scalpel, then <code class="computeroutput"><span class="identifier">relative_difference</span></code>
 | 
						|
          is more like a Swiss army knife: both have important but different use
 | 
						|
          cases.
 | 
						|
        </li>
 | 
						|
</ul></div>
 | 
						|
<h6>
 | 
						|
<a name="math_toolkit.float_comparison.h0"></a>
 | 
						|
      <span class="phrase"><a name="math_toolkit.float_comparison.fp_relative"></a></span><a class="link" href="float_comparison.html#math_toolkit.float_comparison.fp_relative">Relative
 | 
						|
      Comparison of Floating-point Values</a>
 | 
						|
    </h6>
 | 
						|
<p>
 | 
						|
      <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">relative_difference</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
 | 
						|
<a class="link" href="result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">U</span> <span class="identifier">b</span><span class="special">);</span>
 | 
						|
 | 
						|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span>
 | 
						|
<a class="link" href="result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">epsilon_difference</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">U</span> <span class="identifier">b</span><span class="special">);</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      The function <code class="computeroutput"><span class="identifier">relative_difference</span></code>
 | 
						|
      returns the relative distance/error <span class="emphasis"><em>E</em></span> between two values
 | 
						|
      as defined by:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting">E = fabs((a - b) / min(a,b))</pre>
 | 
						|
<p>
 | 
						|
      The function <code class="computeroutput"><span class="identifier">epsilon_difference</span></code>
 | 
						|
      is a convenience function that returns <code class="computeroutput"><span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span>
 | 
						|
      <span class="identifier">b</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">eps</span></code> where
 | 
						|
      <code class="computeroutput"><span class="identifier">eps</span></code> is the machine epsilon
 | 
						|
      for the result type.
 | 
						|
    </p>
 | 
						|
<p>
 | 
						|
      The following special cases are handled as follows:
 | 
						|
    </p>
 | 
						|
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
 | 
						|
<li class="listitem">
 | 
						|
          If either of <span class="emphasis"><em>a</em></span> or <span class="emphasis"><em>b</em></span> is a NaN,
 | 
						|
          then returns the largest representable value for T: for example for type
 | 
						|
          <code class="computeroutput"><span class="keyword">double</span></code>, this is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">double</span><span class="special">>::</span><span class="identifier">max</span><span class="special">()</span></code>
 | 
						|
          which is the same as <code class="computeroutput"><span class="identifier">DBL_MAX</span></code>
 | 
						|
          or <code class="computeroutput"><span class="number">1.7976931348623157e+308</span></code>.
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          If <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span> differ in sign then
 | 
						|
          returns the largest representable value for T.
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          If both <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span> are both infinities
 | 
						|
          (of the same sign), then returns zero.
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          If just one of <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span> is an
 | 
						|
          infinity, then returns the largest representable value for T.
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          If both <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span> are zero then
 | 
						|
          returns zero.
 | 
						|
        </li>
 | 
						|
<li class="listitem">
 | 
						|
          If just one of <span class="emphasis"><em>a</em></span> or <span class="emphasis"><em>b</em></span> is a zero
 | 
						|
          or a denormalized value, then it is treated as if it were the smallest
 | 
						|
          (non-denormalized) value representable in T for the purposes of the above
 | 
						|
          calculation.
 | 
						|
        </li>
 | 
						|
</ul></div>
 | 
						|
<p>
 | 
						|
      These rules were primarily designed to assist with our own test suite, they
 | 
						|
      are designed to be robust enough that the function can in most cases be used
 | 
						|
      blindly, including in cases where the expected result is actually too small
 | 
						|
      to represent in type T and underflows to zero.
 | 
						|
    </p>
 | 
						|
<h6>
 | 
						|
<a name="math_toolkit.float_comparison.h1"></a>
 | 
						|
      <span class="phrase"><a name="math_toolkit.float_comparison.examples"></a></span><a class="link" href="float_comparison.html#math_toolkit.float_comparison.examples">Examples</a>
 | 
						|
    </h6>
 | 
						|
<p>
 | 
						|
      Some using statements will ensure that the functions we need are accessible.
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">;</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      or
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">relative_difference</span><span class="special">;</span>
 | 
						|
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">epsilon_difference</span><span class="special">;</span>
 | 
						|
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">float_next</span><span class="special">;</span>
 | 
						|
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">math</span><span class="special">::</span><span class="identifier">float_prior</span><span class="special">;</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      The following examples display values with all possibly significant digits.
 | 
						|
      Newer compilers should provide <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limitsFPT</span><span class="special">>::</span><span class="identifier">max_digits10</span></code>
 | 
						|
      for this purpose, and here we use <code class="computeroutput"><span class="keyword">float</span></code>
 | 
						|
      precision where <code class="computeroutput"><span class="identifier">max_digits10</span></code>
 | 
						|
      = 9 to avoid displaying a distracting number of decimal digits.
 | 
						|
    </p>
 | 
						|
<div class="note"><table border="0" summary="Note">
 | 
						|
<tr>
 | 
						|
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
 | 
						|
<th align="left">Note</th>
 | 
						|
</tr>
 | 
						|
<tr><td align="left" valign="top"><p>
 | 
						|
        Older compilers can use this formula to calculate <code class="computeroutput"><span class="identifier">max_digits10</span></code>
 | 
						|
        from <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">FPT</span><span class="special">>::</span><span class="identifier">digits10</span></code>:<br>    <code class="computeroutput"><span class="keyword">int</span>
 | 
						|
        <span class="identifier">max_digits10</span> <span class="special">=</span>
 | 
						|
        <span class="number">2</span> <span class="special">+</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="identifier">FPT</span><span class="special">>::</span><span class="identifier">digits10</span>
 | 
						|
        <span class="special">*</span> <span class="number">3010</span><span class="special">/</span><span class="number">10000</span><span class="special">;</span></code>
 | 
						|
      </p></td></tr>
 | 
						|
</table></div>
 | 
						|
<p>
 | 
						|
      One can set the display including all trailing zeros (helpful for this example
 | 
						|
      to show all potentially significant digits), and also to display <code class="computeroutput"><span class="keyword">bool</span></code> values as words rather than integers:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">precision</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">max_digits10</span><span class="special">);</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showpoint</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      When comparing values that are <span class="emphasis"><em>quite close</em></span> or <span class="emphasis"><em>approximately
 | 
						|
      equal</em></span>, we could use either <code class="computeroutput"><span class="identifier">float_distance</span></code>
 | 
						|
      or <code class="computeroutput"><span class="identifier">relative_difference</span></code>/<code class="computeroutput"><span class="identifier">epsilon_difference</span></code>, for example with type
 | 
						|
      <code class="computeroutput"><span class="keyword">float</span></code>, these two values are adjacent
 | 
						|
      to each other:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="keyword">float</span> <span class="identifier">a</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
 | 
						|
<span class="keyword">float</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">1</span> <span class="special">+</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">epsilon</span><span class="special">();</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a = "</span> <span class="special"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"b = "</span> <span class="special"><<</span> <span class="identifier">b</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"float_distance = "</span> <span class="special"><<</span> <span class="identifier">float_distance</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"relative_difference = "</span> <span class="special"><<</span> <span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"epsilon_difference = "</span> <span class="special"><<</span> <span class="identifier">epsilon_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      Which produces the output:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting">a = 1.00000000
 | 
						|
b = 1.00000012
 | 
						|
float_distance = 1.00000000
 | 
						|
relative_difference = 1.19209290e-007
 | 
						|
epsilon_difference = 1.00000000
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      In the example above, it just so happens that the edit distance as measured
 | 
						|
      by <code class="computeroutput"><span class="identifier">float_distance</span></code>, and the
 | 
						|
      difference measured in units of epsilon were equal. However, due to the way
 | 
						|
      floating point values are represented, that is not always the case:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="identifier">a</span> <span class="special">=</span> <span class="number">2.0f</span> <span class="special">/</span> <span class="number">3.0f</span><span class="special">;</span>   <span class="comment">// 2/3 inexactly represented as a float</span>
 | 
						|
<span class="identifier">b</span> <span class="special">=</span> <span class="identifier">float_next</span><span class="special">(</span><span class="identifier">float_next</span><span class="special">(</span><span class="identifier">float_next</span><span class="special">(</span><span class="identifier">a</span><span class="special">)));</span> <span class="comment">// 3 floating point values above a</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a = "</span> <span class="special"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"b = "</span> <span class="special"><<</span> <span class="identifier">b</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"float_distance = "</span> <span class="special"><<</span> <span class="identifier">float_distance</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"relative_difference = "</span> <span class="special"><<</span> <span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"epsilon_difference = "</span> <span class="special"><<</span> <span class="identifier">epsilon_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      Which produces the output:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting">a = 0.666666687
 | 
						|
b = 0.666666865
 | 
						|
float_distance = 3.00000000
 | 
						|
relative_difference = 2.68220901e-007
 | 
						|
epsilon_difference = 2.25000000
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      There is another important difference between <code class="computeroutput"><span class="identifier">float_distance</span></code>
 | 
						|
      and the <code class="computeroutput"><span class="identifier">relative_difference</span><span class="special">/</span><span class="identifier">epsilon_difference</span></code>
 | 
						|
      functions in that <code class="computeroutput"><span class="identifier">float_distance</span></code>
 | 
						|
      returns a signed result that reflects which argument is larger in magnitude,
 | 
						|
      where as <code class="computeroutput"><span class="identifier">relative_difference</span><span class="special">/</span><span class="identifier">epsilon_difference</span></code>
 | 
						|
      simply return an unsigned value that represents how far apart the values are.
 | 
						|
      For example if we swap the order of the arguments:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"float_distance = "</span> <span class="special"><<</span> <span class="identifier">float_distance</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">a</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"relative_difference = "</span> <span class="special"><<</span> <span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">a</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"epsilon_difference = "</span> <span class="special"><<</span> <span class="identifier">epsilon_difference</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">a</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      The output is now:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting">float_distance = -3.00000000
 | 
						|
relative_difference = 2.68220901e-007
 | 
						|
epsilon_difference = 2.25000000
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      Zeros are always treated as equal, as are infinities as long as they have the
 | 
						|
      same sign:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="identifier">a</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
 | 
						|
<span class="identifier">b</span> <span class="special">=</span> <span class="special">-</span><span class="number">0</span><span class="special">;</span>  <span class="comment">// signed zero</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"relative_difference = "</span> <span class="special"><<</span> <span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">a</span> <span class="special">=</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">infinity</span><span class="special">();</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"relative_difference = "</span> <span class="special"><<</span> <span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"relative_difference = "</span> <span class="special"><<</span> <span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="special">-</span><span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      Which produces the output:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting">relative_difference = 0.000000000
 | 
						|
relative_difference = 0.000000000
 | 
						|
relative_difference = 3.40282347e+038
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      Note that finite values are always infinitely far away from infinities even
 | 
						|
      if those finite values are very large:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="identifier">a</span> <span class="special">=</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">max</span><span class="special">)();</span>
 | 
						|
<span class="identifier">b</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">infinity</span><span class="special">();</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a = "</span> <span class="special"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"b = "</span> <span class="special"><<</span> <span class="identifier">b</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"relative_difference = "</span> <span class="special"><<</span> <span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"epsilon_difference = "</span> <span class="special"><<</span> <span class="identifier">epsilon_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      Which produces the output:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting">a = 3.40282347e+038
 | 
						|
b = 1.#INF0000
 | 
						|
relative_difference = 3.40282347e+038
 | 
						|
epsilon_difference = 3.40282347e+038
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      Finally, all denormalized values and zeros are treated as being effectively
 | 
						|
      equal:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="identifier">a</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special"><</span><span class="keyword">float</span><span class="special">>::</span><span class="identifier">denorm_min</span><span class="special">();</span>
 | 
						|
<span class="identifier">b</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">*</span> <span class="number">2</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a = "</span> <span class="special"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"b = "</span> <span class="special"><<</span> <span class="identifier">b</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"float_distance = "</span> <span class="special"><<</span> <span class="identifier">float_distance</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"relative_difference = "</span> <span class="special"><<</span> <span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"epsilon_difference = "</span> <span class="special"><<</span> <span class="identifier">epsilon_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">a</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"a = "</span> <span class="special"><<</span> <span class="identifier">a</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"b = "</span> <span class="special"><<</span> <span class="identifier">b</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"float_distance = "</span> <span class="special"><<</span> <span class="identifier">float_distance</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"relative_difference = "</span> <span class="special"><<</span> <span class="identifier">relative_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"epsilon_difference = "</span> <span class="special"><<</span> <span class="identifier">epsilon_difference</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span> <span class="identifier">b</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      Which produces the output:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting">a = 1.40129846e-045
 | 
						|
b = 2.80259693e-045
 | 
						|
float_distance = 1.00000000
 | 
						|
relative_difference = 0.000000000
 | 
						|
epsilon_difference = 0.000000000
 | 
						|
a = 0.000000000
 | 
						|
b = 2.80259693e-045
 | 
						|
float_distance = 2.00000000
 | 
						|
relative_difference = 0.000000000
 | 
						|
epsilon_difference = 0.000000000</pre>
 | 
						|
<p>
 | 
						|
      Notice how, in the above example, two denormalized values that are a factor
 | 
						|
      of 2 apart are none the less only one representation apart!
 | 
						|
    </p>
 | 
						|
<p>
 | 
						|
      All the above examples are contained in <a href="../../../example/float_comparison_example.cpp" target="_top">float_comparison_example.cpp</a>.
 | 
						|
    </p>
 | 
						|
<h6>
 | 
						|
<a name="math_toolkit.float_comparison.h2"></a>
 | 
						|
      <span class="phrase"><a name="math_toolkit.float_comparison.small"></a></span><a class="link" href="float_comparison.html#math_toolkit.float_comparison.small">Handling
 | 
						|
      Absolute Errors</a>
 | 
						|
    </h6>
 | 
						|
<p>
 | 
						|
      Imagine we're testing the following function:
 | 
						|
    </p>
 | 
						|
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">myspecial</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">x</span><span class="special">)</span>
 | 
						|
<span class="special">{</span>
 | 
						|
   <span class="keyword">return</span> <span class="identifier">sin</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">-</span> <span class="identifier">sin</span><span class="special">(</span><span class="number">4</span> <span class="special">*</span> <span class="identifier">x</span><span class="special">);</span>
 | 
						|
<span class="special">}</span>
 | 
						|
</pre>
 | 
						|
<p>
 | 
						|
      This function has multiple roots, some of which are quite predicable in that
 | 
						|
      both <code class="computeroutput"><span class="identifier">sin</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code> and <code class="computeroutput"><span class="identifier">sin</span><span class="special">(</span><span class="number">4</span><span class="identifier">x</span><span class="special">)</span></code> are zero
 | 
						|
      together. Others occur because the values returned from those two functions
 | 
						|
      precisely cancel out. At such points the relative difference between the true
 | 
						|
      value of the function and the actual value returned may be <span class="emphasis"><em>arbitrarily
 | 
						|
      large</em></span> due to <a href="http://en.wikipedia.org/wiki/Loss_of_significance" target="_top">cancellation
 | 
						|
      error</a>.
 | 
						|
    </p>
 | 
						|
<p>
 | 
						|
      In such a case, testing the function above by requiring that the values returned
 | 
						|
      by <code class="computeroutput"><span class="identifier">relative_error</span></code> or <code class="computeroutput"><span class="identifier">epsilon_error</span></code> are below some threshold is
 | 
						|
      pointless: the best we can do is to verify that the <span class="emphasis"><em>absolute difference</em></span>
 | 
						|
      between the true and calculated values is below some threshold.
 | 
						|
    </p>
 | 
						|
<p>
 | 
						|
      Of course, determining what that threshold should be is often tricky, but a
 | 
						|
      good starting point would be machine epsilon multiplied by the largest of the
 | 
						|
      values being summed. In the example above, the largest value returned by <code class="computeroutput"><span class="identifier">sin</span><span class="special">(</span><span class="identifier">whatever</span><span class="special">)</span></code> is 1, so simply using machine epsilon as the
 | 
						|
      target for maximum absolute difference might be a good start (though in practice
 | 
						|
      we may need a slightly higher value - some trial and error will be necessary).
 | 
						|
    </p>
 | 
						|
</div>
 | 
						|
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
 | 
						|
<td align="left"></td>
 | 
						|
<td align="right"><div class="copyright-footer">Copyright © 2006-2010, 2012-2014 Nikhar Agrawal,
 | 
						|
      Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert
 | 
						|
      Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Johan Råde, Gautam Sewani,
 | 
						|
      Benjamin Sobotta, Thijs van den Berg, Daryle Walker and Xiaogang Zhang<p>
 | 
						|
        Distributed under the Boost Software License, Version 1.0. (See accompanying
 | 
						|
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
 | 
						|
      </p>
 | 
						|
</div></td>
 | 
						|
</tr></table>
 | 
						|
<hr>
 | 
						|
<div class="spirit-nav">
 | 
						|
<a accesskey="p" href="next_float/ulp.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../utils.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../cstdfloat.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
 | 
						|
</div>
 | 
						|
</body>
 | 
						|
</html>
 |