summaryrefslogtreecommitdiff
path: root/libs/math/doc/sf_and_dist/html/math_toolkit/utils/fp_facets/examples.html
blob: 5f80192ea0aae946547f9cc291c128665116bd08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Examples</title>
<link rel="stylesheet" href="../../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.1">
<link rel="home" href="../../../index.html" title="Math Toolkit">
<link rel="up" href="../fp_facets.html" title="Facets for Floating-Point Infinities and NaNs">
<link rel="prev" href="reference.html" title="Reference">
<link rel="next" href="portability.html" title="Portability">
</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="reference.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../fp_facets.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="portability.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section math_toolkit_utils_fp_facets_examples">
<div class="titlepage"><div><div><h4 class="title">
<a name="math_toolkit.utils.fp_facets.examples"></a><a class="link" href="examples.html" title="Examples">Examples</a>
</h4></div></div></div>
<h6>
<a name="math_toolkit.utils.fp_facets.examples.h0"></a>
          <span><a name="math_toolkit.utils.fp_facets.examples.simple_example_with_std__stringstreams"></a></span><a class="link" href="examples.html#math_toolkit.utils.fp_facets.examples.simple_example_with_std__stringstreams">Simple
          example with std::stringstreams</a>
        </h6>
<p>
</p>
<pre class="programlisting"><span class="identifier">locale</span> <span class="identifier">old_locale</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">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>
</pre>
<p>
        </p>
<p>
</p>
<pre class="programlisting"><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="keyword">double</span> <span class="identifier">inf</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">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">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="keyword">double</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">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 double values really are identical.</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">endl</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">endl</span><span class="special">;</span>
<span class="comment">// But the string representation of r displayed will be the native type</span>
<span class="comment">// because, when it was constructed, cout had NOT been imbued</span>
<span class="comment">// with the new locale containing the nonfinite_numput facet.</span>
<span class="comment">// So the cout output will be "1.#INF on MS platforms</span>
<span class="comment">// and may be "inf" or other string representation on other platforms.</span>
</pre>
<p>
        </p>
<h6>
<a name="math_toolkit.utils.fp_facets.examples.h1"></a>
          <span><a name="math_toolkit.utils.fp_facets.examples.use_with_lexical_cast"></a></span><a class="link" href="examples.html#math_toolkit.utils.fp_facets.examples.use_with_lexical_cast">Use
          with lexical_cast</a>
        </h6>
<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>
            From Boost 1.48, lexical_cast no longer uses stringstreams internally,
            and is now able to handle infinities and NaNs natively on most platforms.
          </p></td></tr>
</table></div>
<p>
          Without using a new locale that contains the nonfinite facets, previous
          versions of <code class="computeroutput"><span class="identifier">lexical_cast</span></code>
          using stringstream were not portable (and often failed) if nonfinite values
          are found.
        </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">locale</span> <span class="identifier">old_locale</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">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>
</pre>
<p>
        </p>
<p>
          Although other examples imbue individual streams with the new locale, for
          the streams constructed inside lexical_cast, it was necesary to assign
          to a global locale.
        </p>
<pre class="programlisting"><span class="identifier">locale</span><span class="special">::</span><span class="identifier">global</span><span class="special">(</span><span class="identifier">new_locale</span><span class="special">);</span>
</pre>
<p>
          <code class="computeroutput"><span class="identifier">lexical_cast</span></code> then works
          as expected, even with infinity and NaNs.
        </p>
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">lexical_cast</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;(</span><span class="string">"inf"</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric</span><span class="special">:</span><span class="identifier">limits</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">infinity</span><span class="special">());</span>

<span class="identifier">string</span> <span class="identifier">s</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">lexical_cast</span><span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;(</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">infinity</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">s</span> <span class="special">==</span> <span class="string">"inf"</span><span class="special">);</span>
</pre>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
            If you use stringstream inside your functions, you may still need to
            use a global locale to handle nonfinites correctly. Or you need to imbue
            your stringstream with suitable get and put facets.
          </p></td></tr>
</table></div>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
            You should be aware that the C++ specification does not explicitly require
            that input from decimal digits strings converts with rounding to the
            nearest representable floating-point binary value. (In contrast, decimal
            digits read by the compiler, for example by an assignment like <code class="computeroutput"><span class="keyword">double</span> <span class="identifier">d</span>
            <span class="special">=</span> <span class="number">1.234567890123456789</span></code>,
            are guaranteed to assign the nearest representable value to double d).
            This implies that, no matter how many decimal digits you provide, there
            is a potential uncertainty of 1 least significant bit in the resulting
            binary value.
          </p></td></tr>
</table></div>
<p>
          See <a href="http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding" target="_top">for
          more information on <span class="emphasis"><em>nearest representable</em></span> and <span class="emphasis"><em>rounding</em></span></a>.
        </p>
<p>
          Most iostream libraries do in fact achieve the desirable <span class="emphasis"><em>nearest
          representable floating-point binary value</em></span> for all values of
          input. However one popular STL library does not quite achieve this for
          64-bit doubles. See <a href="http://connect.microsoft.com/VisualStudio/feedback/details/98770/decimal-digit-string-input-to-double-may-be-1-bit-wrong" target="_top">Decimal
          digit string input to double may be 1 bit wrong</a> for the bizarre
          full details.
        </p>
<p>
          If you are expecting to 'round-trip' <code class="computeroutput"><span class="identifier">lexical_cast</span></code>
          or <code class="computeroutput"><span class="identifier">serialization</span></code>, for example
          archiving and loading, and want to be <span class="bold"><strong>absolutely
          certain that you will always get an exactly identical double value binary
          pattern</strong></span>, you should use the suggested 'workaround' below that
          is believed to work on all platforms.
        </p>
<p>
          You should output using all potentially significant decimal digits, by
          setting stream precision to <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_digits10</span></code>,
          (or for the appropriate floating-point type, if not double) and crucially,
          <span class="bold"><strong>require <code class="computeroutput"><span class="identifier">scientific</span></code>
          format</strong></span>, not <code class="computeroutput"><span class="identifier">fixed</span></code>
          or automatic (default), for example:
        </p>
<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">output_value</span> <span class="special">=</span> <span class="identifier">any</span> <span class="identifier">value</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">stringstream</span> <span class="identifier">s</span><span class="special">;</span>
<span class="identifier">s</span> <span class="special">&lt;&lt;</span> <span class="identifier">setprecison</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="special">&lt;&lt;</span> <span class="identifier">scientific</span> <span class="special">&lt;&lt;</span> <span class="identifier">output_value</span><span class="special">;</span>
<span class="identifier">s</span> <span class="special">&gt;&gt;</span> <span class="identifier">input_value</span><span class="special">;</span>
</pre>
<h5>
<a name="math_toolkit.utils.fp_facets.examples.h2"></a>
          <span><a name="math_toolkit.utils.fp_facets.examples.use_with_serialization_archives"></a></span><a class="link" href="examples.html#math_toolkit.utils.fp_facets.examples.use_with_serialization_archives">Use
          with serialization archives</a>
        </h5>
<p>
          It is vital that the same locale is used when an archive is saved and when
          it is loaded. Otherwise, loading the archive may fail. By default, archives
          are saved and loaded with a classic C locale with a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">archive</span><span class="special">::</span><span class="identifier">codecvt_null</span></code>
          facet added. Normally you do not have to worry about that.
        </p>
<p>
          The constructors for the archive classes, as a side-effect, imbue the stream
          with such a locale. However, if you want to use the facets <code class="computeroutput"><span class="identifier">nonfinite_num_put</span></code> and <code class="computeroutput"><span class="identifier">nonfinite_num_get</span></code>
          with archives, then you have to manage the locale manually. That is done
          by calling the archive constructor with the flag <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">archive</span><span class="special">::</span><span class="identifier">no_codecvt</span></code>,
          thereby ensuring that the archive constructor will <span class="bold"><strong>not
          imbue the stream with a new locale</strong></span>.
        </p>
<p>
          The following code shows how to use <code class="computeroutput"><span class="identifier">nonfinite_num_put</span></code>
          with a <code class="computeroutput"><span class="identifier">text_oarchive</span></code>.
        </p>
<pre class="programlisting"><span class="identifier">locale</span> <span class="identifier">default_locale</span><span class="special">(</span><span class="identifier">locale</span><span class="special">::</span><span class="identifier">classic</span><span class="special">(),</span> <span class="keyword">new</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">archive</span><span class="special">::</span><span class="identifier">codecvt_null</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;);</span>
<span class="identifier">locale</span> <span class="identifier">my_locale</span><span class="special">(</span><span class="identifier">default_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">ofstream</span> <span class="identifier">ofs</span><span class="special">(</span><span class="string">"test.txt"</span><span class="special">);</span>
<span class="identifier">ofs</span><span class="special">.</span><span class="identifier">imbue</span><span class="special">(</span><span class="identifier">my_locale</span><span class="special">);</span>

<span class="identifier">boost</span><span class="special">::</span><span class="identifier">archive</span><span class="special">::</span><span class="identifier">text_oarchive</span> <span class="identifier">oa</span><span class="special">(</span><span class="identifier">ofs</span><span class="special">,</span> <span class="identifier">no_codecvt</span><span class="special">);</span>

<span class="keyword">double</span> <span class="identifier">x</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">infinity</span><span class="special">();</span>
<span class="identifier">oa</span> <span class="special">&amp;</span> <span class="identifier">x</span><span class="special">;</span>
</pre>
<p>
          The same method works with <code class="computeroutput"><span class="identifier">nonfinite_num_get</span></code>
          and <code class="computeroutput"><span class="identifier">text_iarchive</span></code>.
        </p>
<p>
          If you use the <code class="computeroutput"><span class="identifier">nonfinite_num_put</span></code>
          with <code class="computeroutput"><span class="identifier">trap_infinity</span></code> and/or
          <code class="computeroutput"><span class="identifier">trap_nan</span></code> flag with a serialization
          archive, then you must set the exception mask of the stream. Serialization
          archives do not check the stream state.
        </p>
<h6>
<a name="math_toolkit.utils.fp_facets.examples.h3"></a>
          <span><a name="math_toolkit.utils.fp_facets.examples.other_examples"></a></span><a class="link" href="examples.html#math_toolkit.utils.fp_facets.examples.other_examples">Other examples</a>
        </h6>
<p>
          <a href="../../../../../../example/nonfinite_facet_simple.cpp" target="_top">nonfinite_facet_simple.cpp</a>
          give some more simple demonstrations of the difference between using classic
          C locale and constructing a C99 infinty and NaN compliant locale for input
          and output.
        </p>
<p>
          See <a href="../../../../../../example/nonfinite_facet_sstream.cpp" target="_top">nonfinite_facet_sstream.cpp</a>
          for this example of use with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">stringstream</span></code>s.
        </p>
<p>
          For an example of how to enforce the MSVC 'legacy' "1.#INF" and
          "1.#QNAN" representations of infinity and NaNs, for input and
          output, see <a href="../../../../../../example/nonfinite_legacy.cpp" target="_top">nonfinite_legacy.cpp</a>.
        </p>
<p>
          Treatment of signaling NaN is demonstrated at <a href="../../../../../../example/nonfinite_signaling_NaN.cpp" target="_top">../../../example/nonfinite_signaling_NaN.cpp</a>
        </p>
<p>
          Example <a href="../../../../../../example/nonfinite_loopback_ok.cpp" target="_top">../../../example/nonfinite_loopback_ok.cpp</a>
          shows loopback works OK.
        </p>
<p>
          Example <a href="../../../../../../example/nonfinite_num_facet.cpp" target="_top">../../../example/nonfinite_num_facet.cpp</a>
          shows output and re-input of various finite and nonfinite values.
        </p>
<p>
          A simple example of trapping nonfinite output is at <a href="../../../../../../example/nonfinite_num_facet_trap.cpp" target="_top">nonfinite_num_facet_trap.cpp</a>.
        </p>
<p>
          A very basic example of using Boost.Archive is at <a href="../../../../../../example/nonfinite_serialization_archives.cpp" target="_top">../../../example/nonfinite_serialization_archives.cpp</a>.
        </p>
<p>
          A full demonstration of serialization by Francois Mauger is at <a href="../../../../../../example/nonfinite_num_facet_serialization.cpp" target="_top">../../../example/nonfinite_num_facet_serialization.cpp</a>
        </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 &#169; 2006-2010 John Maddock, Paul A. Bristow, Hubert Holin, Xiaogang Zhang, Bruno
      Lalande, Johan R&#229;de, Gautam Sewani, Thijs van den Berg and Benjamin Sobotta<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="reference.html"><img src="../../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../fp_facets.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="portability.html"><img src="../../../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>