mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-25 10:00:23 -04: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>
 |