• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Floating-point Comparison</title>
5<link rel="stylesheet" href="../math.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../index.html" title="Math Toolkit 2.12.0">
8<link rel="up" href="../utils.html" title="Chapter 2. Floating Point Utilities">
9<link rel="prev" href="next_float/ulp.html" title="Obtaining the Size of a Unit In the Last Place - ULP">
10<link rel="next" href="cond.html" title="Condition Numbers">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<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="cond.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h2 class="title" style="clear: both">
27<a name="math_toolkit.float_comparison"></a><a class="link" href="float_comparison.html" title="Floating-point Comparison">Floating-point Comparison</a>
28</h2></div></div></div>
29<p>
30      Comparison of floating-point values has always been a source of endless difficulty
31      and confusion.
32    </p>
33<p>
34      Unlike integral values that are exact, all floating-point operations will potentially
35      produce an inexact result that will be rounded to the nearest available binary
36      representation. Even apparently innocuous operations such as assigning 0.1
37      to a double produces an inexact result (as this decimal number has no exact
38      binary representation).
39    </p>
40<p>
41      Floating-point computations also involve rounding so that some 'computational
42      noise' is added, and hence results are also not exact (although repeatable,
43      at least under identical platforms and compile options).
44    </p>
45<p>
46      Sadly, this conflicts with the expectation of most users, as many articles
47      and innumerable cries for help show all too well.
48    </p>
49<p>
50      Some background reading is:
51    </p>
52<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
53<li class="listitem">
54          Knuth D.E. The art of computer programming, vol II, section 4.2, especially
55          Floating-Point Comparison 4.2.2, pages 198-220.
56        </li>
57<li class="listitem">
58          <a href="http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html" target="_top">David
59          Goldberg, "What Every Computer Scientist Should Know About Floating-Point
60          Arithmetic"</a>
61        </li>
62<li class="listitem">
63          <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
64          Squassabia, Comparing floats listing</a>
65        </li>
66<li class="listitem">
67          <a href="https://code.google.com/p/googletest/wiki/AdvancedGuide#Floating-Point_Comparison" target="_top">Google
68          Floating-Point_Comparison guide</a>
69        </li>
70<li class="listitem">
71          <a href="https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/testing_tools/extended_comparison/floating_point.html" target="_top">Boost.Test
72          Floating-Point_Comparison</a>
73        </li>
74</ul></div>
75<p>
76      Boost provides a number of ways to compare floating-point values to see if
77      they are tolerably close enough to each other, but first we must decide what
78      kind of comparison we require:
79    </p>
80<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
81<li class="listitem">
82          Absolute difference/error: the absolute difference between two values
83          <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
84          to make if we know that the result may have cancellation error (see below).
85        </li>
86<li class="listitem">
87          The edit distance between the two values: i.e. how many (binary) floating-point
88          values are between two values <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span>?
89          This is provided by the function <a href="../../../../../libs/math/doc/html/math_toolkit/next_float/float_distance.html" target="_top">Boost.Math
90          float_distance</a>, but is probably only useful when you know that
91          the distance should be very small. This function is somewhat difficult
92          to compute, and doesn't scale to values that are very far apart. In other
93          words, use with care.
94        </li>
95<li class="listitem">
96          The relative distance/error between two values. This is quick and easy
97          to compute, and is generally the method of choice when checking that your
98          results are "tolerably close" to one another. However, it is
99          not as exact as the edit distance when dealing with small differences,
100          and due to the way floating-point values are encoded can "wobble"
101          by a factor of 2 compared to the "true" edit distance. This is
102          the method documented below: if <code class="computeroutput"><span class="identifier">float_distance</span></code>
103          is a surgeon's scalpel, then <code class="computeroutput"><span class="identifier">relative_difference</span></code>
104          is more like a Swiss army knife: both have important but different use
105          cases.
106        </li>
107</ul></div>
108<h6>
109<a name="math_toolkit.float_comparison.h0"></a>
110      <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
111      Comparison of Floating-point Values</a>
112    </h6>
113<p>
114      <code class="computeroutput"><span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span></code>
115    </p>
116<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</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">&gt;</span>
117<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>
118
119<span class="keyword">template</span> <span class="special">&lt;</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">&gt;</span>
120<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>
121</pre>
122<p>
123      The function <code class="computeroutput"><span class="identifier">relative_difference</span></code>
124      returns the relative distance/error <span class="emphasis"><em>E</em></span> between two values
125      as defined by:
126    </p>
127<div class="blockquote"><blockquote class="blockquote"><p>
128        <span class="serif_italic">E = fabs((a - b) / min(a,b))</span>
129      </p></blockquote></div>
130<p>
131      The function <code class="computeroutput"><span class="identifier">epsilon_difference</span></code>
132      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>
133      <span class="identifier">b</span><span class="special">)</span> <span class="special">/</span> <span class="identifier">eps</span></code> where
134      <code class="computeroutput"><span class="identifier">eps</span></code> is the machine epsilon
135      for the result type.
136    </p>
137<p>
138      The following special cases are handled as follows:
139    </p>
140<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
141<li class="listitem">
142          If either of <span class="emphasis"><em>a</em></span> or <span class="emphasis"><em>b</em></span> is a NaN,
143          then returns the largest representable value for T: for example for type
144          <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">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">()</span></code>
145          which is the same as <code class="computeroutput"><span class="identifier">DBL_MAX</span></code>
146          or <code class="computeroutput"><span class="number">1.7976931348623157e+308</span></code>.
147        </li>
148<li class="listitem">
149          If <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span> differ in sign then
150          returns the largest representable value for T.
151        </li>
152<li class="listitem">
153          If both <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span> are both infinities
154          (of the same sign), then returns zero.
155        </li>
156<li class="listitem">
157          If just one of <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span> is an
158          infinity, then returns the largest representable value for T.
159        </li>
160<li class="listitem">
161          If both <span class="emphasis"><em>a</em></span> and <span class="emphasis"><em>b</em></span> are zero then
162          returns zero.
163        </li>
164<li class="listitem">
165          If just one of <span class="emphasis"><em>a</em></span> or <span class="emphasis"><em>b</em></span> is a zero
166          or a denormalized value, then it is treated as if it were the smallest
167          (non-denormalized) value representable in T for the purposes of the above
168          calculation.
169        </li>
170</ul></div>
171<p>
172      These rules were primarily designed to assist with our own test suite, they
173      are designed to be robust enough that the function can in most cases be used
174      blindly, including in cases where the expected result is actually too small
175      to represent in type T and underflows to zero.
176    </p>
177<h6>
178<a name="math_toolkit.float_comparison.h1"></a>
179      <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>
180    </h6>
181<p>
182      Some using statements will ensure that the functions we need are accessible.
183    </p>
184<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>
185</pre>
186<p>
187      or
188    </p>
189<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>
190<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>
191<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>
192<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>
193</pre>
194<p>
195      The following examples display values with all possibly significant digits.
196      Newer compilers should provide <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">FPT</span><span class="special">&gt;::</span><span class="identifier">max_digits10</span></code> for this purpose, and here we
197      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
198      number of decimal digits.
199    </p>
200<div class="note"><table border="0" summary="Note">
201<tr>
202<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
203<th align="left">Note</th>
204</tr>
205<tr><td align="left" valign="top"><p>
206        Older compilers can use this formula to calculate <code class="computeroutput"><span class="identifier">max_digits10</span></code>
207        from <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">FPT</span><span class="special">&gt;::</span><span class="identifier">digits10</span></code>:    <code class="computeroutput"><span class="keyword">int</span>
208        <span class="identifier">max_digits10</span> <span class="special">=</span>
209        <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">&lt;</span><span class="identifier">FPT</span><span class="special">&gt;::</span><span class="identifier">digits10</span>
210        <span class="special">*</span> <span class="number">3010</span><span class="special">/</span><span class="number">10000</span><span class="special">;</span></code>
211      </p></td></tr>
212</table></div>
213<p>
214      One can set the display including all trailing zeros (helpful for this example
215      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:
216    </p>
217<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">&lt;</span><span class="keyword">float</span><span class="special">&gt;::</span><span class="identifier">max_digits10</span><span class="special">);</span>
218<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showpoint</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
219</pre>
220<p>
221      When comparing values that are <span class="emphasis"><em>quite close</em></span> or <span class="emphasis"><em>approximately
222      equal</em></span>, we could use either <code class="computeroutput"><span class="identifier">float_distance</span></code>
223      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
224      <code class="computeroutput"><span class="keyword">float</span></code>, these two values are adjacent
225      to each other:
226    </p>
227<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>
228<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">&lt;</span><span class="keyword">float</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">();</span>
229<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"a = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
230<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"b = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
231<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"float_distance = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
232<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"relative_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
233<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"epsilon_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
234</pre>
235<p>
236      Which produces the output:
237    </p>
238<pre class="programlisting">a = 1.00000000
239b = 1.00000012
240float_distance = 1.00000000
241relative_difference = 1.19209290e-007
242epsilon_difference = 1.00000000
243</pre>
244<p>
245      In the example above, it just so happens that the edit distance as measured
246      by <code class="computeroutput"><span class="identifier">float_distance</span></code>, and the
247      difference measured in units of epsilon were equal. However, due to the way
248      floating point values are represented, that is not always the case:
249    </p>
250<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>
251<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>
252<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"a = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
253<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"b = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
254<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"float_distance = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
255<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"relative_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
256<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"epsilon_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
257</pre>
258<p>
259      Which produces the output:
260    </p>
261<pre class="programlisting">a = 0.666666687
262b = 0.666666865
263float_distance = 3.00000000
264relative_difference = 2.68220901e-007
265epsilon_difference = 2.25000000
266</pre>
267<p>
268      There is another important difference between <code class="computeroutput"><span class="identifier">float_distance</span></code>
269      and the <code class="computeroutput"><span class="identifier">relative_difference</span><span class="special">/</span><span class="identifier">epsilon_difference</span></code>
270      functions in that <code class="computeroutput"><span class="identifier">float_distance</span></code>
271      returns a signed result that reflects which argument is larger in magnitude,
272      where as <code class="computeroutput"><span class="identifier">relative_difference</span><span class="special">/</span><span class="identifier">epsilon_difference</span></code>
273      simply return an unsigned value that represents how far apart the values are.
274      For example if we swap the order of the arguments:
275    </p>
276<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"float_distance = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
277<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"relative_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
278<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"epsilon_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
279</pre>
280<p>
281      The output is now:
282    </p>
283<pre class="programlisting">float_distance = -3.00000000
284relative_difference = 2.68220901e-007
285epsilon_difference = 2.25000000
286</pre>
287<p>
288      Zeros are always treated as equal, as are infinities as long as they have the
289      same sign:
290    </p>
291<pre class="programlisting"><span class="identifier">a</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
292<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>
293<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"relative_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
294<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">&lt;</span><span class="keyword">float</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">();</span>
295<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"relative_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
296<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"relative_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
297</pre>
298<p>
299      Which produces the output:
300    </p>
301<pre class="programlisting">relative_difference = 0.000000000
302relative_difference = 0.000000000
303relative_difference = 3.40282347e+038
304</pre>
305<p>
306      Note that finite values are always infinitely far away from infinities even
307      if those finite values are very large:
308    </p>
309<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">&lt;</span><span class="keyword">float</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">)();</span>
310<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">&lt;</span><span class="keyword">float</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">();</span>
311<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"a = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
312<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"b = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
313<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"relative_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
314<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"epsilon_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
315</pre>
316<p>
317      Which produces the output:
318    </p>
319<pre class="programlisting">a = 3.40282347e+038
320b = 1.#INF0000
321relative_difference = 3.40282347e+038
322epsilon_difference = 3.40282347e+038
323</pre>
324<p>
325      Finally, all denormalized values and zeros are treated as being effectively
326      equal:
327    </p>
328<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">&lt;</span><span class="keyword">float</span><span class="special">&gt;::</span><span class="identifier">denorm_min</span><span class="special">();</span>
329<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>
330<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"a = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
331<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"b = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
332<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"float_distance = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
333<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"relative_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
334<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"epsilon_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
335<span class="identifier">a</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
336<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"a = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">a</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
337<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"b = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">b</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
338<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"float_distance = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
339<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"relative_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
340<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"epsilon_difference = "</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
341</pre>
342<p>
343      Which produces the output:
344    </p>
345<pre class="programlisting">a = 1.40129846e-045
346b = 2.80259693e-045
347float_distance = 1.00000000
348relative_difference = 0.000000000
349epsilon_difference = 0.000000000
350a = 0.000000000
351b = 2.80259693e-045
352float_distance = 2.00000000
353relative_difference = 0.000000000
354epsilon_difference = 0.000000000</pre>
355<p>
356      Notice how, in the above example, two denormalized values that are a factor
357      of 2 apart are none the less only one representation apart!
358    </p>
359<p>
360      All the above examples are contained in <a href="../../../example/float_comparison_example.cpp" target="_top">float_comparison_example.cpp</a>.
361    </p>
362<h6>
363<a name="math_toolkit.float_comparison.h2"></a>
364      <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
365      Absolute Errors</a>
366    </h6>
367<p>
368      Imagine we're testing the following function:
369    </p>
370<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>
371<span class="special">{</span>
372   <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>
373<span class="special">}</span>
374</pre>
375<p>
376      This function has multiple roots, some of which are quite predictable in that
377      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
378      together. Others occur because the values returned from those two functions
379      precisely cancel out. At such points the relative difference between the true
380      value of the function and the actual value returned may be <span class="emphasis"><em>arbitrarily
381      large</em></span> due to <a href="http://en.wikipedia.org/wiki/Loss_of_significance" target="_top">cancellation
382      error</a>.
383    </p>
384<p>
385      In such a case, testing the function above by requiring that the values returned
386      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
387      pointless: the best we can do is to verify that the <span class="emphasis"><em>absolute difference</em></span>
388      between the true and calculated values is below some threshold.
389    </p>
390<p>
391      Of course, determining what that threshold should be is often tricky, but a
392      good starting point would be machine epsilon multiplied by the largest of the
393      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
394      target for maximum absolute difference might be a good start (though in practice
395      we may need a slightly higher value - some trial and error will be necessary).
396    </p>
397</div>
398<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
399<td align="left"></td>
400<td align="right"><div class="copyright-footer">Copyright © 2006-2019 Nikhar
401      Agrawal, Anton Bikineev, Paul A. Bristow, Marco Guazzone, Christopher Kormanyos,
402      Hubert Holin, Bruno Lalande, John Maddock, Jeremy Murphy, Matthew Pulver, Johan
403      Råde, Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg,
404      Daryle Walker and Xiaogang Zhang<p>
405        Distributed under the Boost Software License, Version 1.0. (See accompanying
406        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>)
407      </p>
408</div></td>
409</tr></table>
410<hr>
411<div class="spirit-nav">
412<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="cond.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
413</div>
414</body>
415</html>
416