1[section:fp_facets Facets for Floating-Point Infinities and NaNs] 2 3[import ../../example/nonfinite_facet_sstream.cpp] 4 5[h4 Synopsis] 6 7 namespace boost{ namespace math 8 { 9 // Values for flags. 10 const int legacy; 11 const int signed_zero; 12 const int trap_infinity; 13 const int trap_nan; 14 15 template< 16 class CharType, 17 class OutputIterator = std::ostreambuf_iterator<CharType> 18 > 19 class nonfinite_num_put : public std::num_put<CharType, OutputIterator> 20 { 21 public: 22 explicit nonfinite_num_put(int flags = 0); 23 }; 24 25 template< 26 class CharType, 27 class InputIterator = std::istreambuf_iterator<CharType> 28 > 29 class nonfinite_num_get : public std::num_get<CharType, InputIterator> 30 { 31 public: 32 explicit nonfinite_num_get(int flags = 0); // legacy, sign_zero ... 33 }; 34 }} // namespace boost namespace math 35 36To use these facets 37 38 #include <boost\math\special_functions\nonfinite_num_facets.hpp> 39 40 41[section:facets_intro Introduction] 42 43[h5 The Problem] 44 45The C++98 standard does not specify how ['infinity] and ['NaN] are represented in text streams. 46As a result, different platforms use different string representations. 47This can cause undefined behavior when text files are moved between different platforms. 48Some platforms cannot even input parse their own output! 49So 'route-tripping' or loopback of output to input is not possible. 50For instance, the following test fails with MSVC: 51 52 stringstream ss; 53 double inf = numeric_limits<double>::infinity(); 54 double r; 55 ss << inf; // Write out. 56 ss >> r; // Read back in. 57 58 cout << "infinity output was " << inf << endl; // 1.#INF 59 cout << "infinity input was " << r << endl; // 1 60 61 assert(inf == y); // Fails! 62 63[h5 The Solution] 64 65The facets `nonfinite_num_put` and `nonfinite_num_get` 66format and parse all floating-point numbers, 67including `infinity` and `NaN`, in a consistent and portable manner. 68 69The following test succeeds with MSVC. 70 71[nonfinite_facets_sstream_1] 72 73[tip To add two facets, `nonfinite_num_put` and `nonfinite_num_get`, 74you may have to add one at a time, using a temporary locale. 75 76Or you can create a new locale in one step 77 78`std::locale new_locale(std::locale(std::locale(std::locale(), new boost::math::nonfinite_num_put<char>), new boost::math::nonfinite_num_get<char>));` 79 80and, for example, use it to imbue an input and output stringstream. 81] 82 83[tip To just change an input or output stream, you can concisely write 84`cout.imbue (std::locale(std::locale(), new boost::math::nonfinite_num_put<char>));` 85or 86`cin.imbue (std::locale(std::locale(), new boost::math::nonfinite_num_get<char>));` 87] 88 89[nonfinite_facets_sstream_2] 90 91[h4 C++0X standard for output of infinity and NaN] 92 93[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf C++0X (final) draft standard] 94does not explicitly specify the representation (and input) of nonfinite values, 95leaving it implementation-defined. 96So without some specific action, input and output of nonfinite values is not portable. 97 98[h4 C99 standard for output of infinity and NaN] 99 100The [@http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf C99 standard] 101[*does] specify how infinity and NaN 102are formatted by printf and similar output functions, 103and parsed by scanf and similar input functions. 104 105The following string representations are used: 106 107[table C99 Representation of Infinity and NaN 108[[number] [string]] 109[[Positive infinity]["inf" or "infinity"]] 110[[Positive NaN]["nan" or "nan(...)"]] 111[[Negative infinity]["-inf" or "-infinity"]] 112[[Negative NaN]["-nan" or "-nan(...)"]] 113] 114 115So following C99 provides a sensible 'standard' way 116of handling input and output of nonfinites in C++, 117and this implementation follows most of these formats. 118 119[h5 Signaling NaNs] 120A particular type of NaN is the signaling NaN. 121The usual mechanism of signaling is by raising a floating-point exception. 122Signaling NaNs are defined by 123[@http://en.wikipedia.org/wiki/IEEE_floating-point_standard IEEE 754-2008]. 124 125Floating-point values with layout ['s]111 1111 1['a]xx xxxx xxxx xxxx xxxx xxxx 126where ['s] is the sign, ['x] is the payload, and bit ['a] determines the type of NaN. 127 128If bit ['a] = 1, it is a quiet NaN. 129 130If bit ['a] is zero and the payload ['x] is nonzero, then it is a signaling NaN. 131 132Although there has been theoretical interest in the ability of a signaling NaN 133to raise an exception, for example to prevent use of an uninitialised variable, 134in practice there appears to be no useful application of signaling NaNs for 135most current processors. 136[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf C++0X 18.3.2.2] 137still specifies a (implementation-defined) representation for signaling NaN, 138and `static constexpr bool has_signaling_NaN` 139a method of checking if a floating-point type has a representation for signaling NaN. 140 141But in practice, most platforms treat signaling NaNs in the same as quiet NaNs. 142So, for example, they are represented by "nan" on output in 143[@http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf C99] format, 144and output as `1.#QNAN` by Microsoft compilers. 145 146[note The C99 standard does not distinguish 147between the quiet NaN and signaling NaN values. 148A quiet NaN propagates through almost every arithmetic operation 149without raising a floating-point exception; 150a signaling NaN generally raises a floating-point exception 151when occurring as an arithmetic operand. 152 153C99 specification does not define the behavior of signaling NaNs. 154NaNs created by IEC 60559 operations are always quiet. 155Therefore this implementation follows C99, and treats the signaling NaN bit 156as just a part of the NaN payload field. 157So this implementation does not distinguish between the two classes of NaN.] 158 159[note An implementation may give zero and non-numeric values (such as infinities and NaNs) 160a sign or may leave them unsigned. Wherever such values are unsigned, 161any requirement in the C99 Standard to retrieve the sign shall produce an unspecified sign, 162and any requirement to set the sign shall be ignored. 163 164This might apply to user-defined types, but in practice built-in floating-point 165types `float`, `double` and `long double` have well-behaved signs.] 166 167The numbers can be of type `float`, `double` and `long double`. 168An optional + sign can be used with positive numbers (controlled by ios manipulator `showpos`). 169The function `printf` and similar C++ functions use standard formatting flags 170to put all lower or all upper case 171(controlled by `std::ios` manipulator `uppercase` and `lowercase`). 172 173The function `scanf` and similar input functions are case-insensitive. 174 175The dots in `nan(...)` stand for an arbitrary string. 176The meaning of that string is implementation dependent. 177It can be used to convey extra information about the NaN, from the 'payload'. 178A particular value of the payload might be used to indicate a ['missing value], for example. 179 180This library uses the string representations specified by the C99 standard. 181 182An example of an implementation that optionally includes the NaN payload information is at 183[@http://publib.boulder.ibm.com/infocenter/zos/v1r10/index.jsp?topic=/com.ibm.zos.r10.bpxbd00/fprints.htm AIX NaN fprintf]. 184That implementation specifies for Binary Floating Point NANs: 185 186* A NaN ordinal sequence is a left-parenthesis character '(', 187followed by a digit sequence representing 188an integer n, where 1 <= n <= INT_MAX-1, 189followed by a right-parenthesis character ')'. 190 191* The integer value, n, is determined by the fraction bits of the NaN argument value as follows: 192 193* For a signalling NaN value, NaN fraction bits are reversed (left to right) 194to produce bits (right to left) of an even integer value, 2*n. 195Then formatted output functions produce a (signalling) NaN ordinal sequence 196corresponding to the integer value n. 197 198* For a quiet NaN value, NaN fraction bits are reversed (left to right) 199to produce bits (right to left) of an odd integer value, 2*n-1. 200Then formatted output functions produce a (quiet) NaN ordinal sequence 201corresponding to the integer value n. 202 203[warning This implementation does not (yet) provide output of, or access to, the NaN payload.] 204 205[endsect] [/section:intro Introduction] 206 207[section:reference Reference] 208 209[h5 The Facet `nonfinite_num_put`] 210 211 template< 212 class CharType, class OutputIterator = std::ostreambuf_iterator<CharType> 213 > 214 class nonfinite_num_put; 215 216The `class nonfinite_num_put<CharType, OutputIterator>` 217is derived from `std::num_put<CharType, OutputIterator>`. 218Thus it is a facet that formats numbers. 219The first template argument is the character type of the formatted strings, 220usually `char` or `wchar_t`. 221The second template argument is the type of iterator used to write the strings. 222It is required to be an output iterator. 223Usually the default `std::ostreambuf_iterator` is used. 224The public interface of the class consists of a single constructor only: 225 226 nonfinite_num_put(int flags = 0); 227 228The flags argument (effectively optional because a default of ` no_flags` is provided) 229is discussed below. 230The class template `nonfinite_num_put` is defined in the 231header `boost/math/nonfinite_num_facets.hpp` 232and lives in the namespace `boost::math`. 233 234Unlike the C++ Standard facet `std::num_put`, the facet `nonfinite_num_put` 235formats `infinity` and `NaN` in a consistent and portable manner. 236It uses the following string representations: 237 238[table 239[[Number][String]] 240[[Positive infinity][inf]] 241[[Positive NaN][nan]] 242[[Negative infinity][-inf]] 243[[Negative NaN][-nan]] 244] 245 246The numbers can be of type `float`, `double` and `long double`. 247The strings can be in all lower case or all upper case. 248An optional + sign can be used with positive numbers. 249This can be controlled with the `uppercase`, `lowercase`, `showpos` and `noshowpos` manipulators. 250Formatting of integers, boolean values and finite floating-point numbers is simply delegated to the normal `std::num_put`. 251 252 253[h5 Facet `nonfinite_num_get`] 254 255 template<class CharType, class InputIterator = std::istreambuf_iterator<CharType> > class nonfinite_num_get; 256 257The class `nonfinite_num_get<CharType, InputIterator>` is derived from `std::num_get<CharType, IntputIterator>`. 258Thus it is a facet that parses strings that represent numbers. 259The first template argument is the character type of the strings, 260usually `char` or `wchar_t`. 261The second template argument is the type of iterator used to read the strings. 262It is required to be an input iterator. Usually the default is used. 263The public interface of the class consists of a single constructor only: 264 265 nonfinite_num_get(int flags = 0); 266 267The flags argument is discussed below. 268The `class template nonfinite_num_get` is defined 269in the header `boost/math/nonfinite_num_facets.hpp` 270and lives in the `namespace boost::math`. 271 272Unlike the facet `std::num_get`, the facet `nonfinite_num_get` parses strings 273that represent `infinity` and `NaN` in a consistent and portable manner. 274It recognizes precisely the string representations specified by the C99 standard: 275 276[table 277[[Number][String]] 278[[Positive infinity][inf, infinity]] 279[[Positive NaN][nan, nan(...)]] 280[[Negative infinity][-inf, -infinity]] 281[[Negative NaN][-nan, -nan(...)]] 282] 283 284The numbers can be of type `float`, `double` and `long double`. 285The facet is case-insensitive. An optional + sign can be used with positive numbers. 286The dots in nan(...) stand for an arbitrary string usually containing the ['NaN payload]. 287Parsing of strings that represent integers, boolean values 288and finite floating-point numbers is delegated to `std::num_get`. 289 290When the facet parses a string that represents `infinity` on a platform that lacks infinity, 291then the fail bit of the stream is set. 292 293When the facet parses a string that represents `NaN` on a platform that lacks NaN, 294then the fail bit of the stream is set. 295 296[h4 Flags] 297 298The constructors for `nonfinite_num_put` and `nonfinite_num_get` 299take an optional bit flags argument. 300There are four different bit flags: 301 302* legacy 303* signed_zero 304* trap_infinity 305* trap_nan 306 307The flags can be combined with the OR `operator|`. 308 309The flags are defined in the header `boost/math/nonfinite_num_facets.hpp` 310and live in the `namespace boost::math`. 311 312[h5 legacy] 313 314The legacy flag has no effect with the output facet `nonfinite_num_put`. 315 316If the legacy flag is used with the `nonfinite_num_get` input facet, 317then the facet will recognize all the following string representations of `infinity` and `NaN`: 318 319[table 320[[Number][String]] 321[[Positive infinity][inf, infinity, one#inf]] 322[[Positive NaN][nan, nan(...), nanq, nans, qnan, snan, one#ind, one#qnan, one#snan]] 323[[Negative infinity][-inf, -infinity, -one#inf]] 324[[Negative NaN][-nan, -nan(...), -nanq, -nans, -qnan, -snan, -one#ind, - one#qnan, -one#snan]] 325] 326 327* The numbers can be of type `float`, `double` and `long double`. 328* The facet is case-insensitive. 329* An optional `+` sign can be used with the positive values. 330* The dots in `nan(...)` stand for an arbitrary string. 331* `one` stands for any string that `std::num_get` parses as the number `1`, 332typically "1.#INF", "1.QNAN" but also "000001.#INF"... 333 334The list includes a number of non-standard string representations of infinity and NaN 335that are used by various existing implementations of the C++ standard library, 336and also string representations used by other programming languages. 337 338[h5 signed_zero] 339 340If the `signed_zero` flag is used with `nonfinite_num_put`, 341then the facet will always distinguish between positive and negative zero. 342It will format positive zero as "0" or "+0" and negative zero as "-0". 343The string representation of positive zero can be controlled 344with the `showpos` and `noshowpos` manipulators. 345 346The `signed_zero flag` has no effect with the input facet `nonfinite_num_get`. 347The input facet `nonfinite_num_get` always parses "0" and "+0" 348as positive zero and "-0" as negative zero, 349as do most implementations of `std::num_get`. 350 351[note If the `signed_zero` flag is not set (the default), then a negative zero value 352will be displayed on output in whatever way the platform normally handles it. 353For most platforms, this it will format positive zero as "0" or "+0" and negative zero as "-0". 354But setting the `signed_zero` flag may be more portable.] 355 356[tip A negative zero value can be portably produced using the changesign function 357`(changesign)(static_cast<ValType>(0))` where `ValType` is `float`, `double` or `long double`, 358 or a User-Defined floating-point type (UDT) provided that this UDT has a sign 359and that the changesign function is implemented.] 360 361[h5 trap_infinity] 362 363If the `trap_infinity` flag is used with `nonfinite_num_put`, 364then the facet will throw an exception of type `std::ios_base::failure` 365when an attempt is made to format positive or negative infinity. 366If the facet is called from a stream insertion operator, 367then the stream will catch that exception and set either its `fail bit` or its `bad bit`. 368Which bit is set is platform dependent. 369 370If the `trap_infinity` flag is used with `nonfinite_num_get`, 371then the facet will set the `fail bit` of the stream when an attempt is made 372to parse a string that represents positive or negative infinity. 373 374 375(See Design Rationale below for a discussion of this inconsistency.) 376 377[h5 trap_nan] 378 379Same as `trap_infinity`, but positive and negative NaN are trapped instead. 380 381[endsect] [/section:reference Reference] 382 383 384[section:examples Examples] 385 386[h5 Simple example with std::stringstreams] 387 388[nonfinite_facets_sstream_1] 389[nonfinite_facets_sstream_2] 390 391[h5 Use with lexical_cast] 392 393[note From Boost 1.48, lexical_cast no longer uses stringstreams internally, 394and is now able to handle infinities and NaNs natively on most platforms.] 395 396Without using a new locale that contains the nonfinite facets, 397previous versions of `lexical_cast` using stringstream were not portable 398(and often failed) if nonfinite values are found. 399 400[nonfinite_facets_sstream_1] 401 402Although other examples imbue individual streams with the new locale, 403for the streams constructed inside lexical_cast, 404it was necessary to assign to a global locale. 405 406 locale::global(new_locale); 407 408`lexical_cast` then works as expected, even with infinity and NaNs. 409 410 double x = boost::lexical_cast<double>("inf"); 411 assert(x == std::numeric:limits<double>::infinity()); 412 413 string s = boost::lexical_cast<string>(numeric_limits<double>::infinity()); 414 assert(s == "inf"); 415 416[warning If you use stringstream inside your functions, 417you may still need to use a global locale to handle nonfinites correctly. 418Or you need to imbue your stringstream with suitable get and put facets.] 419 420[warning You should be aware that the C++ specification does not explicitly require 421that input from decimal digits strings converts with rounding to the 422nearest representable floating-point binary value. 423(In contrast, decimal digits read by the compiler, 424for example by an assignment like `double d = 1.234567890123456789`, 425are guaranteed to assign the nearest representable value to double d). 426This implies that, no matter how many decimal digits you provide, 427there is a potential uncertainty of 1 least significant bit in the resulting binary value.] 428 429See [@http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding conversion and rounding] 430for more information on ['nearest representable] and ['rounding] and 431[@http://www.exploringbinary.com/ Exploring Binary] for much detail on input and round-tripping difficulties. 432 433Most iostream libraries do in fact achieve the desirable 434['nearest representable floating-point binary value] for all values of input. 435However one popular STL library does not quite achieve this for 64-bit doubles. See 436[@http://connect.microsoft.com/VisualStudio/feedback/details/98770/decimal-digit-string-input-to-double-may-be-1-bit-wrong 437Decimal digit string input to double may be 1 bit wrong] for the bizarre full details. 438 439If you are expecting to 'round-trip' `lexical_cast` or `serialization`, 440for example archiving and loading, 441and want to be [*absolutely certain that you will 442always get an exactly identical double value binary pattern], 443you should use the suggested 'workaround' below that is believed to work on all platforms. 444 445You should output using all potentially significant decimal digits, 446by setting stream precision to `std::numeric_limits<double>::max_digits10`, 447(or for the appropriate floating-point type, if not double) 448and crucially, [*require `scientific` format], not `fixed` or automatic (default), for example: 449 450 double output_value = any value; 451 std::stringstream s; 452 s << setprecison(std::numeric_limits<double>::max_digits10) << scientific << output_value; 453 s >> input_value; 454 455 456[h4 Use with serialization archives] 457 458It is vital that the same locale is used 459when an archive is saved and when it is loaded. 460Otherwise, loading the archive may fail. 461By default, archives are saved and loaded with a classic C locale 462with a `boost::archive::codecvt_null` facet added. 463Normally you do not have to worry about that. 464 465The constructors for the archive classes, as a side-effect, 466imbue the stream with such a locale. 467However, if you want to use the 468facets `nonfinite_num_put` and `nonfinite_num_get` with archives, 469then you have to manage the locale manually. 470That is done by calling the archive constructor with the flag 471`boost::archive::no_codecvt`, thereby ensuring that the archive constructor 472will [*not imbue the stream with a new locale]. 473 474The following code shows how to use `nonfinite_num_put` with a `text_oarchive`. 475 476 locale default_locale(locale::classic(), new boost::archive::codecvt_null<char>); 477 locale my_locale(default_locale, new nonfinite_num_put<char>); 478 479 ofstream ofs("test.txt"); 480 ofs.imbue(my_locale); 481 482 boost::archive::text_oarchive oa(ofs, no_codecvt); 483 484 double x = numeric_limits<double>::infinity(); 485 oa & x; 486 487The same method works with `nonfinite_num_get` and `text_iarchive`. 488 489If you use the `nonfinite_num_put` with `trap_infinity` 490and/or `trap_nan` flag with a serialization archive, 491then you must set the exception mask of the stream. 492Serialization archives do not check the stream state. 493 494 495[h5 Other examples] 496 497[@../../example/nonfinite_facet_simple.cpp nonfinite_facet_simple.cpp] 498give some more simple demonstrations of the difference between using classic C locale 499and constructing a C99 infinity and NaN compliant locale for input and output. 500 501See [@../../example/nonfinite_facet_sstream.cpp nonfinite_facet_sstream.cpp] 502for this example of use with `std::stringstream`s. 503 504For an example of how to enforce the MSVC 'legacy' 505"1.#INF" and "1.#QNAN" representations of infinity and NaNs, 506for input and output, 507see [@../../example/nonfinite_legacy.cpp nonfinite_legacy.cpp]. 508 509Treatment of signaling NaN is demonstrated at 510[@../../example/nonfinite_signaling_NaN.cpp] 511 512Example [@../../example/nonfinite_loopback_ok.cpp] shows loopback works OK. 513 514Example [@../../example/nonfinite_num_facet.cpp] shows output and re-input 515of various finite and nonfinite values. 516 517A simple example of trapping nonfinite output is at 518[@../../example/nonfinite_num_facet_trap.cpp nonfinite_num_facet_trap.cpp]. 519 520A very basic example of using Boost.Archive is at 521[@../../example/nonfinite_serialization_archives.cpp]. 522 523A full demonstration of serialization by Francois Mauger is at 524[@../../example/nonfinite_num_facet_serialization.cpp] 525 526[endsect] [/section:examples Examples] 527 528[section:portability Portability] 529 530This library uses the floating-point number classification and sign-bit from Boost.Math library, 531and should work on all platforms where that library works. 532See the portability information for that library. 533 534[endsect] [/section:portability Portability] 535 536[section:rationale Design Rationale] 537 538* The flags are implemented as a const data member of the facet. 539Facets are reference counted, and locales can share facets. 540Therefore changing the flags of a facet would have effects that are hard to predict. 541An alternative design would be to implement the flags 542using `std::ios_base::xalloc` and `std::ios_base::iword`. 543Then one could safely modify the flags, and one could define manipulators that do so. 544However, for that to work with dynamically linked libraries, 545a `.cpp` file would have to be added to the library. 546It was judged be more desirable to have a header-only library, 547than to have mutable flags and manipulators. 548 549* The facet `nonfinite_num_put` throws an exception when 550the `trap_infinity` or `trap_nan` flag is set 551and an attempt is made to format infinity or NaN. 552It would be better if the facet set the `fail bit` of the stream. 553However, facets derived from `std::num_put` do not have access to the stream state. 554 555[endsect] [/section:rationale Design Rationale] 556 557[endsect] [/section:fp_facets Facets for Floating-Point Infinities and NaNs] 558 559[/ 560 Copyright Johan Rade and Paul A. Bristow 2011. 561 Distributed under the Boost Software License, Version 1.0. 562 (See accompanying file LICENSE_1_0.txt or copy at 563 http://www.boost.org/LICENSE_1_0.txt). 564] 565 566 567 568 569