2021-10-05 21:37:46 +02:00

553 lines
63 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>std::numeric_limits&lt;&gt; functions</title>
<link rel="stylesheet" href="../../../multiprecision.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../../index.html" title="Chapter 1. Boost.Multiprecision">
<link rel="up" href="../limits.html" title="Numeric Limits">
<link rel="prev" href="constants.html" title="std::numeric_limits&lt;&gt; constants">
<link rel="next" href="limits32.html" title="Numeric limits for 32-bit platform">
</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="constants.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../limits.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="limits32.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_multiprecision.tut.limits.functions"></a><a class="link" href="functions.html" title="std::numeric_limits&lt;&gt; functions"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;&gt;</span></code> functions</a>
</h4></div></div></div>
<h5>
<a name="boost_multiprecision.tut.limits.functions.h0"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.max_function"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.max_function"><code class="computeroutput"><span class="identifier">max</span></code> function</a>
</h5>
<p>
Function <code class="computeroutput"><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">T</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">)()</span></code> returns the largest finite value that
can be represented by the type T. If there is no such value (and <code class="computeroutput"><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">bounded</span></code> is <code class="computeroutput"><span class="keyword">false</span></code>)
then returns <code class="computeroutput"><span class="identifier">T</span><span class="special">()</span></code>.
</p>
<p>
For <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
(built-in)</a> types there is usually a corresponding MACRO value TYPE_MAX,
where TYPE is CHAR, INT, FLOAT etc.
</p>
<p>
Other types, including those provided by a typedef, for example <code class="computeroutput"><span class="identifier">INT64_T_MAX</span></code> for <code class="computeroutput"><span class="identifier">int64_t</span></code>,
may provide a macro definition.
</p>
<p>
To cater for situations where no <code class="computeroutput"><span class="identifier">numeric_limits</span></code>
specialization is available (for example because the precision of the type
varies at runtime), packaged versions of this (and other functions) are
provided using
</p>
<pre class="programlisting"><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">tools</span><span class="special">/</span><span class="identifier">precision</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="identifier">T</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">tools</span><span class="special">::</span><span class="identifier">max_value</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;();</span>
</pre>
<p>
Of course, these simply use <code class="computeroutput"><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">T</span><span class="special">&gt;::</span><span class="identifier">max</span><span class="special">)()</span></code>
if available, but otherwise 'do something sensible'.
</p>
<h5>
<a name="boost_multiprecision.tut.limits.functions.h1"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.lowest_function"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.lowest_function">lowest
function</a>
</h5>
<p>
Since C++11: <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">T</span><span class="special">&gt;::</span><span class="identifier">lowest</span><span class="special">()</span></code>
is
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
For integral types, the same as function <code class="computeroutput"><span class="identifier">min</span><span class="special">()</span></code>.
</li>
<li class="listitem">
For floating-point types, generally the negative of <code class="computeroutput"><span class="identifier">max</span><span class="special">()</span></code> (but implementation-dependent).
</li>
</ul></div>
<pre class="programlisting"><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">double</span><span class="special">&gt;::</span><span class="identifier">max</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">double</span><span class="special">&gt;::</span><span class="identifier">lowest</span><span class="special">();</span>
</pre>
<h5>
<a name="boost_multiprecision.tut.limits.functions.h2"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.min_function"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.min_function"><code class="computeroutput"><span class="identifier">min</span></code> function</a>
</h5>
<p>
Function <code class="computeroutput"><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">T</span><span class="special">&gt;::</span><span class="identifier">min</span><span class="special">)()</span></code> returns the minimum finite value that
can be represented by the type T.
</p>
<p>
For <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
(built-in)</a> types, there is usually a corresponding MACRO value
TYPE_MIN, where TYPE is CHAR, INT, FLOAT etc.
</p>
<p>
Other types, including those provided by a <code class="computeroutput"><span class="keyword">typedef</span></code>,
for example, <code class="computeroutput"><span class="identifier">INT64_T_MIN</span></code>
for <code class="computeroutput"><span class="identifier">int64_t</span></code>, may provide
a macro definition.
</p>
<p>
For floating-point types, it is more fully defined as the <span class="emphasis"><em>minimum
positive normalized value</em></span>.
</p>
<p>
See <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">T</span><span class="special">&gt;::</span><span class="identifier">denorm_min</span><span class="special">()</span></code>
for the smallest denormalized value, provided
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">has_denorm</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">denorm_present</span>
</pre>
<p>
To cater for situations where no <code class="computeroutput"><span class="identifier">numeric_limits</span></code>
specialization is available (for example because the precision of the type
varies at runtime), packaged versions of this (and other functions) are
provided using
</p>
<pre class="programlisting"><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">tools</span><span class="special">/</span><span class="identifier">precision</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="identifier">T</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">tools</span><span class="special">::</span><span class="identifier">min_value</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;();</span>
</pre>
<p>
Of course, these simply use <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">T</span><span class="special">&gt;::</span><span class="identifier">min</span><span class="special">()</span></code> if available.
</p>
<h5>
<a name="boost_multiprecision.tut.limits.functions.h3"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.denorm_min_function"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.denorm_min_function">denorm_min
function</a>
</h5>
<p>
Function <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">T</span><span class="special">&gt;::</span><span class="identifier">denorm_min</span><span class="special">()</span></code>
returns the smallest <a href="http://en.wikipedia.org/wiki/Denormal_number" target="_top">denormalized
value</a>, provided
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">has_denorm</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">denorm_present</span>
</pre>
<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">double</span><span class="special">&gt;::</span><span class="identifier">max_digits10</span><span class="special">);</span>
<span class="keyword">if</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">double</span><span class="special">&gt;::</span><span class="identifier">has_denorm</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">denorm_present</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">double</span> <span class="identifier">d</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">double</span><span class="special">&gt;::</span><span class="identifier">denorm_min</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">d</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> <span class="comment">// 4.9406564584124654e-324</span>
<span class="keyword">int</span> <span class="identifier">exponent</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">significand</span> <span class="special">=</span> <span class="identifier">frexp</span><span class="special">(</span><span class="identifier">d</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">exponent</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"exponent = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">hex</span> <span class="special">&lt;&lt;</span> <span class="identifier">exponent</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> <span class="comment">// fffffbcf</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"significand = "</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">hex</span> <span class="special">&lt;&lt;</span> <span class="identifier">significand</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> <span class="comment">// 0.50000000000000000</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"No denormalization. "</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>
<span class="special">}</span>
</pre>
<p>
The exponent is effectively reduced from -308 to -324 (though it remains
encoded as zero and leading zeros appear in the significand, thereby losing
precision until the significand reaches zero).
</p>
<h5>
<a name="boost_multiprecision.tut.limits.functions.h4"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.round_error"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.round_error">round_error</a>
</h5>
<p>
Function <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">T</span><span class="special">&gt;::</span><span class="identifier">round_error</span><span class="special">()</span></code>
returns the maximum error (in units of <a href="http://en.wikipedia.org/wiki/Unit_in_the_last_place" target="_top">Unit
in the last place (ULP)</a>) that can be caused by any basic arithmetic
operation.
</p>
<pre class="programlisting"><span class="identifier">round_style</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">round_indeterminate</span><span class="special">;</span>
</pre>
<p>
The rounding style is indeterminable at compile time.
</p>
<p>
For floating-point types, when rounding is to nearest, only half a bit
is lost by rounding, and <code class="computeroutput"><span class="identifier">round_error</span>
<span class="special">==</span> <span class="number">0.5</span></code>.
In contrast when rounding is towards zero, or plus/minus infinity, we can
loose up to one bit from rounding, and <code class="computeroutput"><span class="identifier">round_error</span>
<span class="special">==</span> <span class="number">1</span></code>.
</p>
<p>
For integer types, rounding always to zero, so at worst almost one bit
can be rounded, so <code class="computeroutput"><span class="identifier">round_error</span>
<span class="special">==</span> <span class="number">1</span></code>.
</p>
<p>
<code class="computeroutput"><span class="identifier">round_error</span><span class="special">()</span></code>
can be used with <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">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">()</span></code>
to estimate the maximum potential error caused by rounding. For typical
floating-point types, <code class="computeroutput"><span class="identifier">round_error</span><span class="special">()</span> <span class="special">=</span> <span class="number">1</span><span class="special">/</span><span class="number">2</span></code>, so half
epsilon is the maximum potential error.
</p>
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">round_err</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">double</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">()</span> <span class="comment">// 2.2204460492503131e-016</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">double</span><span class="special">&gt;::</span><span class="identifier">round_error</span><span class="special">();</span> <span class="comment">// 1/2</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">round_err</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> <span class="comment">// 1.1102230246251565e-016</span>
</pre>
<p>
There are, of course, many occasions when much bigger loss of precision
occurs, for example, caused by <a href="http://en.wikipedia.org/wiki/Loss_of_significance" target="_top">Loss
of significance or cancellation error</a> or very many iterations.
</p>
<h5>
<a name="boost_multiprecision.tut.limits.functions.h5"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.epsilon"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.epsilon">epsilon</a>
</h5>
<p>
Function <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">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">()</span></code>
is meaningful only for non-integral types.
</p>
<p>
It returns the difference between <code class="computeroutput"><span class="number">1.0</span></code>
and the next value representable by the floating-point type T. So it is
a one least-significant-bit change in this floating-point value.
</p>
<p>
For <code class="computeroutput"><span class="keyword">double</span></code> (<code class="computeroutput"><span class="identifier">float_64t</span></code>) it is <code class="computeroutput"><span class="number">2.2204460492503131e-016</span></code>
showing all possibly significant 17 decimal digits.
</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">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">max_digits10</span><span class="special">);</span>
<span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">1.</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">eps</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">double</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">();</span>
<span class="keyword">double</span> <span class="identifier">dpeps</span> <span class="special">=</span> <span class="identifier">d</span><span class="special">+</span><span class="identifier">eps</span><span class="special">;</span>
<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">showpoint</span> <span class="comment">// Ensure all trailing zeros are shown.</span>
<span class="special">&lt;&lt;</span> <span class="identifier">d</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span> <span class="comment">// 1.0000000000000000</span>
<span class="special">&lt;&lt;</span> <span class="identifier">dpeps</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> <span class="comment">// 2.2204460492503131e-016</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">dpeps</span> <span class="special">-</span> <span class="identifier">d</span> <span class="comment">// 1.0000000000000002</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>
</pre>
<p>
We can explicitly increment by one bit using the function <code class="computeroutput"><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></code>
and the result is the same as adding <code class="computeroutput"><span class="identifier">epsilon</span></code>.
</p>
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">one</span> <span class="special">=</span> <span class="number">1.</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">nad</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">float_next</span><span class="special">(</span><span class="identifier">one</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">nad</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span> <span class="comment">// 1.0000000000000002</span>
<span class="special">&lt;&lt;</span> <span class="identifier">nad</span> <span class="special">-</span> <span class="identifier">one</span> <span class="comment">// 2.2204460492503131e-016</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>
</pre>
<p>
Adding any smaller value, like half <code class="computeroutput"><span class="identifier">epsilon</span></code>,
will have no effect on this value.
</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">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">max_digits10</span><span class="special">);</span>
<span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">1.</span><span class="special">;</span>
<span class="keyword">double</span> <span class="identifier">eps</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">double</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">();</span>
<span class="keyword">double</span> <span class="identifier">dpeps</span> <span class="special">=</span> <span class="identifier">d</span> <span class="special">+</span> <span class="identifier">eps</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">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">showpoint</span> <span class="comment">// Ensure all trailing zeros are shown.</span>
<span class="special">&lt;&lt;</span> <span class="identifier">dpeps</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span> <span class="comment">// 1.0000000000000000</span>
<span class="special">&lt;&lt;</span> <span class="identifier">eps</span><span class="special">/</span><span class="number">2</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> <span class="comment">// 1.1102230246251565e-016</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">dpeps</span> <span class="special">-</span> <span class="identifier">d</span> <span class="comment">// 0.00000000000000000</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>
</pre>
<p>
So this cancellation error leaves the values equal, despite adding half
<code class="computeroutput"><span class="identifier">epsilon</span></code>.
</p>
<p>
To achieve greater portability over platform and floating-point type, Boost.Math
and Boost.Multiprecision provide a package of functions that 'do something
sensible' if the standard <code class="computeroutput"><span class="identifier">numeric_limits</span></code>
is not available. To use these <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">tools</span><span class="special">/</span><span class="identifier">precision</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>.
</p>
<p>
A tolerance might be defined using this version of epsilon thus:
</p>
<pre class="programlisting"><span class="identifier">RealType</span> <span class="identifier">tolerance</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">tools</span><span class="special">::</span><span class="identifier">epsilon</span><span class="special">&lt;</span><span class="identifier">RealType</span><span class="special">&gt;()</span> <span class="special">*</span> <span class="number">2</span><span class="special">;</span>
</pre>
<h6>
<a name="boost_multiprecision.tut.limits.functions.h6"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.FP_tolerance"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.FP_tolerance">Tolerance
for Floating-point Comparisons</a>
</h6>
<p>
<a href="https://en.wikipedia.org/wiki/Machine_epsilon" target="_top">Machine epsilon
ε</a> is very useful to compute a tolerance when comparing floating-point
values, a much more difficult task than is commonly imagined.
</p>
<p>
The C++ standard specifies <a href="https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;&gt;::</span><span class="identifier">epsilon</span><span class="special">()</span></code></a>
and Boost.Multiprecision implements this (where possible) for its program-defined
types analogous to the <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
(built-in)</a> floating-point types like <code class="computeroutput"><span class="keyword">double</span></code>
<code class="computeroutput"><span class="keyword">float</span></code>.
</p>
<p>
For more information than you probably want (but still need) see <a href="http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html" target="_top">What
Every Computer Scientist Should Know About Floating-Point Arithmetic</a>
</p>
<p>
The naive test comparing the absolute difference between two values and
a tolerance does not give useful results if the values are too large or
too small.
</p>
<p>
So Boost.Test uses an algorithm first devised by Knuth for reliably checking
if floating-point values are close enough.
</p>
<p>
See Donald. E. Knuth. The art of computer programming (vol II). Copyright
1998 Addison-Wesley Longman, Inc., 0-201-89684-2. Addison-Wesley Professional;
3rd edition. (The relevant equations are in paragraph 4.2.2, Eq. 36 and
37.)
</p>
<p>
See <a href="https://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/testing_tools/extended_comparison/floating_point/floating_points_comparison_theory.html" target="_top">Boost.Math
floating_point comparison</a> for more details.
</p>
<p>
See also:
</p>
<p>
<a href="http://adtmag.com/articles/2000/03/15/comparing-floats-how-to-determine-if-floating-quantities-are-close-enough-once-a-tolerance-has-been.aspx" target="_top">Alberto
Squassia, Comparing floats</a>
</p>
<p>
<a href="http://adtmag.com/articles/2000/03/16/comparing-floats-how-to-determine-if-floating-quantities-are-close-enough-once-a-tolerance-has-been.aspx" target="_top">Alberto
Squassia, Comparing floats code</a>
</p>
<p>
<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
Floating-Point_Comparison</a>
</p>
<p>
For example, if we want a tolerance that might suit about 9 arithmetical
operations, say sqrt(9) = 3, we could define:
</p>
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">tolerance</span> <span class="special">=</span> <span class="number">3</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">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">();</span>
</pre>
<p>
This is very widely used in Boost.Math testing with Boost.Test's macro
<code class="computeroutput"><span class="identifier">BOOST_CHECK_CLOSE_FRACTION</span></code>
</p>
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">expected</span> <span class="special">=</span> <span class="number">1.0</span><span class="special">;</span>
<span class="identifier">T</span> <span class="identifier">calculated</span> <span class="special">=</span> <span class="number">1.0</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">T</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">();</span>
<span class="identifier">BOOST_CHECK_CLOSE_FRACTION</span><span class="special">(</span><span class="identifier">expected</span><span class="special">,</span> <span class="identifier">calculated</span><span class="special">,</span> <span class="identifier">tolerance</span><span class="special">);</span>
</pre>
<p>
used thus:
</p>
<pre class="programlisting"><span class="identifier">cd</span> <span class="special">./</span><span class="identifier">test</span>
<span class="identifier">BOOST_CHECK_CLOSE_FRACTION</span><span class="special">(</span><span class="identifier">expected</span><span class="special">,</span> <span class="identifier">calculated</span><span class="special">,</span> <span class="identifier">tolerance</span><span class="special">);</span>
</pre>
<p>
(There is also a version BOOST_CHECK_CLOSE using tolerance as a <span class="bold"><strong>percentage</strong></span> rather than a fraction; usually the fraction
version is simpler to use).
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">number</span><span class="special">;</span>
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_dec_float</span><span class="special">;</span>
<span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">et_off</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">number</span><span class="special">&lt;</span><span class="identifier">cpp_dec_float</span><span class="special">&lt;</span><span class="number">50</span><span class="special">&gt;,</span> <span class="identifier">et_off</span> <span class="special">&gt;</span> <span class="identifier">cpp_dec_float_50</span><span class="special">;</span> <span class="comment">// 50 decimal digits.</span>
</pre>
<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>
that Boost.Test does not yet allow floating-point comparisons with expression
templates on, so the default expression template parameter has been replaced
by <code class="computeroutput"><span class="identifier">et_off</span></code>.
</p></td></tr>
</table></div>
<pre class="programlisting"><span class="identifier">cpp_dec_float_50</span> <span class="identifier">tolerance</span> <span class="special">=</span> <span class="number">3</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">cpp_dec_float_50</span><span class="special">&gt;::</span><span class="identifier">epsilon</span><span class="special">();</span>
<span class="identifier">cpp_dec_float_50</span> <span class="identifier">expected</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">constants</span><span class="special">::</span><span class="identifier">two_pi</span><span class="special">&lt;</span><span class="identifier">cpp_dec_float_50</span><span class="special">&gt;();</span>
<span class="identifier">cpp_dec_float_50</span> <span class="identifier">calculated</span> <span class="special">=</span> <span class="number">2</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">constants</span><span class="special">::</span><span class="identifier">pi</span><span class="special">&lt;</span><span class="identifier">cpp_dec_float_50</span><span class="special">&gt;();</span>
<span class="identifier">BOOST_CHECK_CLOSE_FRACTION</span><span class="special">(</span><span class="identifier">expected</span><span class="special">,</span> <span class="identifier">calculated</span><span class="special">,</span> <span class="identifier">tolerance</span><span class="special">);</span>
</pre>
<h5>
<a name="boost_multiprecision.tut.limits.functions.h7"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.infinity"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.infinity">Infinity -
positive and negative</a>
</h5>
<p>
For floating-point types only, for which <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">T</span><span class="special">&gt;::</span><span class="identifier">has_infinity</span>
<span class="special">==</span> <span class="keyword">true</span></code>,
function <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">T</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">()</span></code>
provides an implementation-defined representation for ∞.
</p>
<p>
The 'representation' is a particular bit pattern reserved for infinity.
For IEEE754 system (for which <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">T</span><span class="special">&gt;::</span><span class="identifier">is_iec559</span>
<span class="special">==</span> <span class="keyword">true</span></code>)
<a href="http://en.wikipedia.org/wiki/IEEE_754-1985#Positive_and_negative_infinity" target="_top">positive
and negative infinity</a> are assigned bit patterns for all defined
floating-point types.
</p>
<p>
Confusingly, the string resulting from outputting this representation,
is also implementation-defined. And the string that can be input to generate
the representation is also implementation-defined.
</p>
<p>
For example, the output is <code class="computeroutput"><span class="number">1.</span><span class="special">#</span><span class="identifier">INF</span></code>
on Microsoft systems, but <code class="computeroutput"><span class="identifier">inf</span></code>
on most *nix platforms.
</p>
<p>
This implementation-defined-ness has hampered use of infinity (and NaNs)
but <a href="https://www.boost.org/doc/libs/release/libs/math/doc/index.html" target="_top">Boost.Math</a>
and <a href="https://www.boost.org/doc/libs/release/libs/multiprecision/doc/index.html" target="_top">Boost.Multiprecision</a>
work hard to provide a sensible representation for <span class="bold"><strong>all</strong></span>
floating-point types, not just the <a href="https://en.cppreference.com/w/cpp/language/types" target="_top">fundamental
(built-in) types</a>, which with the use of suitable facets to define
the input and output strings, makes it possible to use these useful features
portably and including <a href="https://www.boost.org/doc/libs/release/libs/serialization/doc/index.html" target="_top">Boost.Serialization</a>.
</p>
<h5>
<a name="boost_multiprecision.tut.limits.functions.h8"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.not_a_number_nan"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.not_a_number_nan">Not-A-Number
NaN</a>
</h5>
<h6>
<a name="boost_multiprecision.tut.limits.functions.h9"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.quiet_nan"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.quiet_nan">Quiet_NaN</a>
</h6>
<p>
For floating-point types only, for which <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">T</span><span class="special">&gt;::</span><span class="identifier">has_quiet_NaN</span>
<span class="special">==</span> <span class="keyword">true</span></code>,
function <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">T</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">()</span></code>
provides an implementation-defined representation for NaN.
</p>
<p>
<a href="http://en.wikipedia.org/wiki/NaN" target="_top">NaNs</a> are values to
indicate that the result of an assignment or computation is meaningless.
A typical example is <code class="computeroutput"><span class="number">0</span><span class="special">/</span><span class="number">0</span></code> but there are many others.
</p>
<p>
NaNs may also be used, to represent missing values: for example, these
could, by convention, be ignored in calculations of statistics like means.
</p>
<p>
Many of the problems with a representation for <a href="http://en.wikipedia.org/wiki/NaN" target="_top">Not-A-Number</a>
has hampered portable use, similar to those with infinity.
</p>
<p>
NaN can be used with binary multiprecision types like <code class="computeroutput"><span class="identifier">cpp_bin_float_quad</span></code>:
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_bin_float_quad</span><span class="special">;</span>
<span class="keyword">if</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">cpp_bin_float_quad</span><span class="special">&gt;::</span><span class="identifier">has_quiet_NaN</span> <span class="special">==</span> <span class="keyword">true</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">cpp_bin_float_quad</span> <span class="identifier">NaN</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">cpp_bin_float_quad</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"cpp_bin_float_quad NaN is "</span> <span class="special">&lt;&lt;</span> <span class="identifier">NaN</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> <span class="comment">// cpp_bin_float_quad NaN is nan</span>
<span class="identifier">cpp_bin_float_quad</span> <span class="identifier">expected</span> <span class="special">=</span> <span class="identifier">NaN</span><span class="special">;</span>
<span class="identifier">cpp_bin_float_quad</span> <span class="identifier">calculated</span> <span class="special">=</span> <span class="number">2</span> <span class="special">*</span> <span class="identifier">NaN</span><span class="special">;</span>
<span class="comment">// Comparisons of NaN's always fail:</span>
<span class="keyword">bool</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">expected</span> <span class="special">==</span> <span class="identifier">calculated</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</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>
<span class="identifier">BOOST_CHECK_NE</span><span class="special">(</span><span class="identifier">expected</span><span class="special">,</span> <span class="identifier">expected</span><span class="special">);</span>
<span class="identifier">BOOST_CHECK_NE</span><span class="special">(</span><span class="identifier">expected</span><span class="special">,</span> <span class="identifier">calculated</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Type "</span> <span class="special">&lt;&lt;</span> <span class="keyword">typeid</span><span class="special">(</span><span class="identifier">cpp_bin_float_quad</span><span class="special">).</span><span class="identifier">name</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">" does not have NaNs!"</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>
<span class="special">}</span>
</pre>
<p>
But using Boost.Math and suitable facets can permit portable use of both
NaNs and positive and negative infinity.
</p>
<p>
See <a href="http://www.boost.org/doc/libs/release/libs/multiprecision/doc/html/../../../../libs/math/example/nonfinite_facet_sstream.cpp" target="_top">boost:/libs/math/example/nonfinite_facet_sstream.cpp</a>
and we also need
</p>
<pre class="programlisting"><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">nonfinite_num_facets</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
Then we can equally well use a multiprecision type cpp_bin_float_quad:
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">multiprecision</span><span class="special">::</span><span class="identifier">cpp_bin_float_quad</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">cpp_bin_float_quad</span> <span class="identifier">T</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">nonfinite_num_put</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">nonfinite_num_get</span><span class="special">;</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">locale</span> <span class="identifier">old_locale</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">locale</span> <span class="identifier">tmp_locale</span><span class="special">(</span><span class="identifier">old_locale</span><span class="special">,</span> <span class="keyword">new</span> <span class="identifier">nonfinite_num_put</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">locale</span> <span class="identifier">new_locale</span><span class="special">(</span><span class="identifier">tmp_locale</span><span class="special">,</span> <span class="keyword">new</span> <span class="identifier">nonfinite_num_get</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">stringstream</span> <span class="identifier">ss</span><span class="special">;</span>
<span class="identifier">ss</span><span class="special">.</span><span class="identifier">imbue</span><span class="special">(</span><span class="identifier">new_locale</span><span class="special">);</span>
<span class="identifier">T</span> <span class="identifier">inf</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">T</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">();</span>
<span class="identifier">ss</span> <span class="special">&lt;&lt;</span> <span class="identifier">inf</span><span class="special">;</span> <span class="comment">// Write out.</span>
<span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">ss</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"inf"</span><span class="special">);</span>
<span class="identifier">T</span> <span class="identifier">r</span><span class="special">;</span>
<span class="identifier">ss</span> <span class="special">&gt;&gt;</span> <span class="identifier">r</span><span class="special">;</span> <span class="comment">// Read back in.</span>
<span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">inf</span> <span class="special">==</span> <span class="identifier">r</span><span class="special">);</span> <span class="comment">// Confirms that the floating-point values really are identical.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"infinity output was "</span> <span class="special">&lt;&lt;</span> <span class="identifier">ss</span><span class="special">.</span><span class="identifier">str</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>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"infinity input was "</span> <span class="special">&lt;&lt;</span> <span class="identifier">r</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>
<span class="special">}</span>
</pre>
<pre class="programlisting"><span class="identifier">infinity</span> <span class="identifier">output</span> <span class="identifier">was</span> <span class="identifier">inf</span>
<span class="identifier">infinity</span> <span class="identifier">input</span> <span class="identifier">was</span> <span class="identifier">inf</span>
</pre>
<p>
Similarly we can do the same with NaN (except that we cannot use <code class="computeroutput"><span class="identifier">assert</span></code> (because any comparisons with
NaN always return false).
</p>
<pre class="programlisting"><span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">locale</span> <span class="identifier">old_locale</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">locale</span> <span class="identifier">tmp_locale</span><span class="special">(</span><span class="identifier">old_locale</span><span class="special">,</span> <span class="keyword">new</span> <span class="identifier">nonfinite_num_put</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">locale</span> <span class="identifier">new_locale</span><span class="special">(</span><span class="identifier">tmp_locale</span><span class="special">,</span> <span class="keyword">new</span> <span class="identifier">nonfinite_num_get</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">stringstream</span> <span class="identifier">ss</span><span class="special">;</span>
<span class="identifier">ss</span><span class="special">.</span><span class="identifier">imbue</span><span class="special">(</span><span class="identifier">new_locale</span><span class="special">);</span>
<span class="identifier">T</span> <span class="identifier">n</span><span class="special">;</span>
<span class="identifier">T</span> <span class="identifier">NaN</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">T</span><span class="special">&gt;::</span><span class="identifier">quiet_NaN</span><span class="special">();</span>
<span class="identifier">ss</span> <span class="special">&lt;&lt;</span> <span class="identifier">NaN</span><span class="special">;</span> <span class="comment">// Write out.</span>
<span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">ss</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">==</span> <span class="string">"nan"</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"NaN output was "</span> <span class="special">&lt;&lt;</span> <span class="identifier">ss</span><span class="special">.</span><span class="identifier">str</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>
<span class="identifier">ss</span> <span class="special">&gt;&gt;</span> <span class="identifier">n</span><span class="special">;</span> <span class="comment">// Read back in.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"NaN input was "</span> <span class="special">&lt;&lt;</span> <span class="identifier">n</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>
<span class="special">}</span>
</pre>
<pre class="programlisting"><span class="identifier">NaN</span> <span class="identifier">output</span> <span class="identifier">was</span> <span class="identifier">nan</span>
<span class="identifier">NaN</span> <span class="identifier">input</span> <span class="identifier">was</span> <span class="identifier">nan</span>
</pre>
<h6>
<a name="boost_multiprecision.tut.limits.functions.h10"></a>
<span class="phrase"><a name="boost_multiprecision.tut.limits.functions.signaling_nan"></a></span><a class="link" href="functions.html#boost_multiprecision.tut.limits.functions.signaling_nan">Signaling
NaN</a>
</h6>
<p>
For floating-point types only, for which <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">T</span><span class="special">&gt;::</span><span class="identifier">has_signaling_NaN</span>
<span class="special">==</span> <span class="keyword">true</span></code>,
function <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">T</span><span class="special">&gt;::</span><span class="identifier">signaling_NaN</span><span class="special">()</span></code>
provides an implementation-defined representation for NaN that causes a
hardware trap. It should be noted however, that at least one implementation
of this function causes a hardware trap to be triggered simply by calling
<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">T</span><span class="special">&gt;::</span><span class="identifier">signaling_NaN</span><span class="special">()</span></code>,
and not only by using the value returned.
</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 © 2002-2020 John
Maddock and Christopher Kormanyos<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="constants.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../limits.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="limits32.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>