cstdfloat.qbk 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. [/cstdfloat.qbk Specified-width floating-point typedefs]
  2. [def __IEEE754 [@http://en.wikipedia.org/wiki/IEEE_floating_point IEEE_floating_point]]
  3. [def __N3626 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3626.pdf N3626]]
  4. [def __N1703 [@http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1703.pdf N1703]]
  5. [import ../../example/cstdfloat_example.cpp]
  6. [import ../../example/normal_tables.cpp]
  7. [/Removed as unhelpful for C++ users, but might have use as a check that quadmath is available and linked OK.]
  8. [/import ../../example/quadmath_snprintf.c]
  9. [section:specified_typedefs Overview]
  10. The header `<boost/cstdfloat.hpp>` provides [*optional]
  11. standardized floating-point `typedef`s having [*specified widths].
  12. These are useful for writing portable code because they
  13. should behave identically on all platforms.
  14. These `typedef`s are the floating-point analog of specified-width integers in `<cstdint>` and `stdint.h`.
  15. The `typedef`s are based on __N3626
  16. proposed for a new C++14 standard header `<cstdfloat>` and
  17. __N1703 proposed for a new C language standard header `<stdfloat.h>`.
  18. All `typedef`s are in `namespace boost` (would be in namespace `std` if eventually standardized).
  19. The `typedef`s include `float16_t, float32_t, float64_t, float80_t, float128_t`,
  20. their corresponding least and fast types,
  21. and the corresponding maximum-width type.
  22. The `typedef`s are based on underlying built-in types
  23. such as `float`, `double`, or `long double`, or the proposed __short_float,
  24. or based on other compiler-specific non-standardized types such as `__float128`.
  25. The underlying types of these `typedef`s must conform with
  26. the corresponding specifications of binary16, binary32, binary64,
  27. and binary128 in __IEEE754 floating-point format, and
  28. `std::numeric_limits<>::is_iec559 == true`.
  29. The 128-bit floating-point type (of great interest in scientific and
  30. numeric programming) is not required in the Boost header,
  31. and may not be supplied for all platforms/compilers, because compiler
  32. support for a 128-bit floating-point type is not mandated by either
  33. the C standard or the C++ standard.
  34. If 128-bit floating-point is supported, then including `boost/cstdfloat.hpp`
  35. provides a [*native] 128-bit type, and
  36. includes other headers in folder `boost/math/cstdfloat` that provide C++
  37. quad support for __C_math in `<cmath>`, `<limits>`, `<iostream>`, `<complex>`,
  38. and the available floating-point types.
  39. One can also, more robustly, include `boost/multiprecision/float128.hpp`
  40. and this provides a thin wrapper selecting the appropriate 128-bit native type
  41. from `cstdfloat` if available, or else a 128-bit multiprecision type.
  42. See [link math_toolkit.examples.je_lambda Jahnke-Emden-Lambda function example]
  43. for an example using both a `<cmath>` function and a Boost.Math function
  44. to evaluate a moderately interesting function, the
  45. [@http://mathworld.wolfram.com/LambdaFunction.html Jahnke-Emden-Lambda function]
  46. and [link math_toolkit.examples.normal_table normal distribution]
  47. as an example of a statistical distribution from Boost.Math.
  48. [endsect] [/section:specified_typedefs Overview]
  49. [section:rationale Rationale]
  50. The implementation of `<boost/cstdfloat.hpp>` is designed to utilize `<float.h>`,
  51. defined in the 1989 C standard. The preprocessor is used to query certain
  52. preprocessor definitions in `<float.h>` such as FLT_MAX, DBL_MAX, etc.
  53. Based on the results of these queries, an attempt is made to automatically
  54. detect the presence of built-in floating-point types having specified widths.
  55. An unequivocal test requiring conformance with __IEEE754 (IEC599) based on
  56. [@ http://en.cppreference.com/w/cpp/types/numeric_limits/is_iec559 `std::numeric_limits<>::is_iec559`]
  57. is performed with `BOOST_STATIC_ASSERT`.
  58. In addition, this Boost implementation `<boost/cstdfloat.hpp>`
  59. supports an 80-bit floating-point `typedef` if it can be detected,
  60. and a 128-bit floating-point `typedef` if it can be detected,
  61. provided that the underlying types conform with
  62. [@http://en.wikipedia.org/wiki/Extended_precision IEEE-754 precision extension]
  63. (provided `std::numeric_limits<>::is_iec559 == true` for this type).
  64. The header `<boost/cstdfloat.hpp>` makes the standardized floating-point
  65. `typedef`s safely available in `namespace boost` without placing any names
  66. in `namespace std`. The intention is to complement rather than compete
  67. with a potential future C/C++ Standard Library that may contain these `typedef`s.
  68. Should some future C/C++ standard include `<stdfloat.h>` and `<cstdfloat>`,
  69. then `<boost/cstdfloat.hpp>` will continue to function, but will become redundant
  70. and may be safely deprecated.
  71. Because `<boost/cstdfloat.hpp>` is a Boost header, its name conforms to the
  72. boost header naming conventions, not the C++ Standard Library header
  73. naming conventions.
  74. [note
  75. `<boost/cstdfloat.hpp>` [*cannot synthesize or create
  76. a `typedef` if the underlying type is not provided by the compiler].
  77. For example, if a compiler does not have an underlying floating-point
  78. type with 128 bits (highly sought-after in scientific and numeric programming),
  79. then `float128_t` and its corresponding least and fast types are [*not]
  80. provided by `<boost/cstdfloat.hpp`>.]
  81. [warning If `<boost/cstdfloat.hpp>` uses a compiler-specific non-standardized type
  82. ([*not] derived from `float, double,` or `long double`) for one or more
  83. of its floating-point `typedef`s, then there is no guarantee that
  84. specializations of `numeric_limits<>` will be available for these types.
  85. Typically, specializations of `numeric_limits<>` will only be available for these
  86. types if the compiler itself supports corresponding specializations
  87. for the underlying type(s), exceptions are GCC's `__float128` type and
  88. Intel's `_Quad` type which are explicitly supported via our own code.]
  89. [warning
  90. As an implementation artifact, certain C macro names from `<float.h>`
  91. may possibly be visible to users of `<boost/cstdfloat.hpp>`.
  92. Don't rely on using these macros; they are not part of any Boost-specified interface.
  93. Use `std::numeric_limits<>` for floating-point ranges, etc. instead.]
  94. [tip For best results, `<boost/cstdfloat.hpp>` should be `#include`d before
  95. other headers that define generic code making use of standard library functions
  96. defined in <cmath>.
  97. This is because `<boost/cstdfloat.hpp>` may define overloads of
  98. standard library functions where a non-standard type (i.e. other than
  99. `float`, `double`, or `long double`) is used for one of the specified
  100. width types. If generic code (for example in another Boost.Math header)
  101. calls a standard library function, then the correct overload will only be
  102. found if these overloads are defined prior to the point of use.
  103. See [link math_toolkit.float128.overloading overloading template functions with float128_t]
  104. and the implementation of `cstdfloat.hpp` for more details.
  105. For this reason, making `#include <boost/cstdfloat.hpp>` the [*first
  106. include] is usually best.
  107. ]
  108. [endsect] [/section:rationale Rationale]
  109. [section:exact_typdefs Exact-Width Floating-Point `typedef`s]
  110. The `typedef float#_t`, with # replaced by the width, designates a
  111. floating-point type of exactly # bits. For example `float32_t` denotes
  112. a single-precision floating-point type with approximately
  113. 7 decimal digits of precision (equivalent to binary32 in __IEEE754).
  114. Floating-point types in C and C++ are specified to be allowed to have
  115. (optionally) implementation-specific widths and formats.
  116. However, if a platform supports underlying
  117. floating-point types (conformant with __IEEE754) with widths of
  118. 16, 32, 64, 80, 128 bits, or any combination thereof,
  119. then `<boost/cstdfloat.hpp>` does provide the corresponding `typedef`s
  120. `float16_t, float32_t, float64_t, float80_t, float128_t,`
  121. their corresponding least and fast types,
  122. and the corresponding maximum-width type.
  123. [h4 How to tell which widths are supported]
  124. The definition (or not) of a
  125. [link math_toolkit.macros floating-point constant macro]
  126. is a way to test if a [*specific width floating-point] is available on a platform.
  127. #if defined(BOOST_FLOAT16_C)
  128. // Can use boost::float16_t, perhaps a proposed __short_float.
  129. // P0192R1, Adding Fundamental Type for Short Float,
  130. // Boris Fomitchev, Sergei Nikolaev, Olivier Giroux, Lawrence Crowl, 2016 Feb14
  131. // http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2016.pdf
  132. #endif
  133. #if defined(BOOST_FLOAT32_C)
  134. // Can use boost::float32_t, usually type `float`.
  135. #endif
  136. #if defined(BOOST_FLOAT64_C)
  137. // Can use boost::float64_t, usually type `double`, and sometimes also type `long double`.
  138. #endif
  139. #if defined(BOOST_FLOAT80_C)
  140. // Can use boost::float80_t, sometimes type `long double`.
  141. #endif
  142. #if defined(BOOST_FLOAT128_C)
  143. // Can use boost::float128_t. Sometimes type `__float128` or `_Quad`.
  144. #endif
  145. This can be used to write code which will compile and run (albeit differently) on several platforms.
  146. Without these tests, if a width, say `float128_t` is not supported, then compilation would fail.
  147. (It is, of course, rare for `float64_t` or `float32_t` not to be supported).
  148. The number of bits in just the significand can be determined using:
  149. std::numeric_limits<boost::floatmax_t>::digits
  150. and from this one can safely infer the total number of bits because the type must be IEEE754 format,
  151. `std::numeric_limits<boost::floatmax_t>::is_iec559 == true`,
  152. so, for example, if `std::numeric_limits<boost::floatmax_t>::digits == 113`,
  153. then `floatmax_t` must be` float128_t`.
  154. The [*total] number of bits using `floatmax_t` can be found thus:
  155. [floatmax_1]
  156. and the number of 'guaranteed' decimal digits using
  157. std::numeric_limits<boost::floatmax_t>::digits10
  158. and the maximum number of possibly significant decimal digits using
  159. std::numeric_limits<boost::floatmax_t>::max_digits10
  160. [tip `max_digits10` is not always supported,
  161. but can be calculated at compile-time using the Kahan formula,
  162. `2 + binary_digits * 0.3010` which can be calculated [*at compile time] using
  163. `2 + binary_digits * 3010/10000`.
  164. ]
  165. [note One could test that
  166. std::is_same<boost::floatmax_t, boost::float128_t>::value == true
  167. but this would fail to compile on a platform where `boost::float128_t` is not defined.
  168. So it is better to use the MACROs `BOOST_FLOATnnn_C`. ]
  169. [endsect] [/section:exact_typdefs Exact-Width Floating-Point `typedef`s]
  170. [section:minimum_typdefs Minimum-width floating-point `typedef`s]
  171. The `typedef float_least#_t`, with # replaced by the width, designates a
  172. floating-point type with a [*width of at least # bits], such that no
  173. floating-point type with lesser size has at least the specified width.
  174. Thus, `float_least32_t` denotes the smallest floating-point type with
  175. a width of at least 32 bits.
  176. Minimum-width floating-point types are provided for all existing
  177. exact-width floating-point types on a given platform.
  178. For example, if a platform supports `float32_t` and `float64_t`,
  179. then `float_least32_t` and `float_least64_t` will also be supported, etc.
  180. [endsect] [/section:minimum_typdefs Minimum-width floating-point `typedef`s]
  181. [section:fastest_typdefs Fastest floating-point `typedef`s]
  182. The `typedef float_fast#_t`, with # replaced by the width, designates
  183. the [*fastest] floating-point type with a [*width of at least # bits].
  184. There is no absolute guarantee that these types are the fastest for all purposes.
  185. In any case, however, they satisfy the precision and width requirements.
  186. Fastest minimum-width floating-point types are provided for all existing
  187. exact-width floating-point types on a given platform.
  188. For example, if a platform supports `float32_t` and `float64_t`,
  189. then `float_fast32_t` and `float_fast64_t` will also be supported, etc.
  190. [endsect] [/section:fastest_typdefs Fastest floating-point `typedef`s]
  191. [section:greatest_typdefs Greatest-width floating-point typedef]
  192. The `typedef floatmax_t` designates a floating-point type capable of representing
  193. any value of any floating-point type in a given platform most precisely.
  194. The greatest-width `typedef` is provided for all platforms, but, of course, the size may vary.
  195. To provide floating-point [*constants] most precisely representable for a `floatmax_t` type,
  196. use the macro `BOOST_FLOATMAX_C`.
  197. For example, replace a constant `123.4567890123456789012345678901234567890` with
  198. BOOST_FLOATMAX_C(123.4567890123456789012345678901234567890)
  199. If, for example, `floatmax_t` is `float64_t` then the result will be equivalent to a `long double` suffixed with L,
  200. but if `floatmax_t` is `float128_t` then the result will be equivalent to a `quad type` suffixed with Q
  201. (assuming, of course, that `float128_t` (`__float128` or `Quad`) is supported).
  202. If we display with `max_digits10`, the maximum possibly significant decimal digits:
  203. [floatmax_widths_1]
  204. then on a 128-bit platform (GCC 4.8.1 or higher with quadmath):
  205. [floatmax_widths_2]
  206. [endsect] [/section:greatest_typdefs Greatest-width floating-point typedef]
  207. [section:macros Floating-Point Constant Macros]
  208. All macros of the type `BOOST_FLOAT16_C, BOOST_FLOAT32_C, BOOST_FLOAT64_C,
  209. BOOST_FLOAT80_C, BOOST_FLOAT128_C, ` and `BOOST_FLOATMAX_C`
  210. are always defined after inclusion of `<boost/cstdfloat.hpp>`.
  211. [cstdfloat_constant_2]
  212. [tip Boost.Math provides many constants 'built-in', so always use Boost.Math constants if available, for example:]
  213. [cstdfloat_constant_1]
  214. from [@../../example/cstdfloat_example.cpp cstdfloat_example.cpp].
  215. See the complete list of __constants.
  216. [endsect] [/section:macros Floating-Point Constant Macros]
  217. [section:examples Examples]
  218. [h3:je_lambda Jahnke-Emden-Lambda function]
  219. The following code uses `<boost/cstdfloat.hpp>` in combination with
  220. `<boost/math/special_functions.hpp>` to compute a simplified
  221. version of the
  222. [@http://mathworld.wolfram.com/LambdaFunction.html Jahnke-Emden-Lambda function].
  223. Here, we specify a floating-point type with [*exactly 64 bits] (i.e., `float64_t`).
  224. If we were to use, for instance, built-in `double`,
  225. then there would be no guarantee that the code would
  226. behave identically on all platforms. With `float64_t` from
  227. `<boost/cstdfloat.hpp>`, however, it is very likely to be identical.
  228. Using `float64_t`, we know that
  229. this code is as portable as possible and uses a floating-point type
  230. with approximately 15 decimal digits of precision,
  231. regardless of the compiler or version or operating system.
  232. [cstdfloat_example_1]
  233. [cstdfloat_example_2]
  234. [cstdfloat_example_3]
  235. For details, see [@../../example/cstdfloat_example.cpp cstdfloat_example.cpp]
  236. - a extensive example program.
  237. [h3:normal_table Normal distribution table]
  238. This example shows printing tables of a normal distribution's PDF and CDF,
  239. using `boost::math` implementation of normal distribution.
  240. A function templated on floating-point type prints a table for a range of standard variate z values.
  241. The example shows use of the specified-width typedefs to either use a specific width,
  242. or to use the maximum available on the platform, perhaps a high as 128-bit.
  243. The number of digits displayed is controlled by the precision of the type,
  244. so there are no spurious insignificant decimal digits:
  245. float_32_t 0 0.39894228
  246. float_128_t 0 0.398942280401432702863218082711682655
  247. Some sample output for two different platforms is appended to the code at
  248. [@../../example/normal_tables.cpp normal_tables.cpp].
  249. [normal_table_1]
  250. [endsect] [/section:examples examples]
  251. [section:float128_hints Hints on using float128 (and __float128)]
  252. [h5:different_float128 __float128 versus float128]
  253. * __float128 is the (optionally) compiler supplied hardware type,
  254. it's an C-ish extension to C++ and there is only
  255. minimal support for it in normal C++
  256. (no IO streams or `numeric_limits` support,
  257. function names in libquadmath all have different names to the
  258. `std::` ones etc.)
  259. So you can program type `__float128` directly, but it's harder work.
  260. * Type `float128` uses __float128 and makes it C++ and generic code friendly,
  261. with all the usual standard `iostream`, `numeric_limits`, `complex` in namspace `std::` available,
  262. so strongly recommended for C++ use.
  263. [h5 Hints and tips]
  264. * Make sure you declare variables with the correct type, here `float128`.
  265. * Make sure that if you pass a variable to a function then it is casted to `float128`.
  266. * Make sure you declare literals with the correct suffix - otherwise
  267. they'll be treated as type `double` with catastrophic loss of precision.
  268. So make sure they have a Q suffix for 128-bit floating-point literals.
  269. * All the std library functions, cmath functions, plus all the constants, and special
  270. functions from Boost.Math should then just work.
  271. * Make sure std lib functions are called [*unqualified] so that the correct
  272. overload is found via __ADL. So write
  273. sqrt(variable)
  274. and not
  275. std::sqrt(variable).
  276. * In general, try not to reinvent stuff - using constants from
  277. Boost.Math is probably less error prone than declaring your own,
  278. likewise the special functions etc.
  279. Some examples of what can go horribly and silently wrong are at
  280. [@../../example/float128_example.cpp float128_example.cpp].
  281. [endsect] [/section:float128_hints Hints on using float128]
  282. [section:float128 Implementation of Float128 type]
  283. Since few compilers implement a true 128-bit floating-point, and language features like the suffix Q
  284. (which may need an option `-fext-numeric-literals` to enable),
  285. and C++ Standard library functions are as-yet missing or incomplete in C++11,
  286. this Boost.Math implementation wraps `__float128` provided by the GCC compiler
  287. [@https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html GCC floating-point types]
  288. or the `_Quad` type provided by the Intel compiler.
  289. This is provided to in order to demonstrate, and users to evaluate, the feasibility and benefits of higher-precision floating-point,
  290. especially to allow use of the full <cmath> and Boost.Math library of functions and distributions at high precision.
  291. (It is also possible to use Boost.Math with Boost.Multiprecision decimal and binary, but since these are entirely software solutions,
  292. allowing much higher precision or arbitrary precision, they are likely to be slower).
  293. We also provide (we believe full) support for `<limits>, <cmath>`, I/O stream operations in `<iostream>`, and `<complex>`.
  294. As a prototype for a future C++ standard, we place all these in `namespace std`.
  295. This contravenes the existing C++ standard of course, so selecting any compiler that promises to check conformance will fail.
  296. [tip For GCC, compile with `-std=gnu++11` or `-std=gnu++03` and do not use `-std=stdc++11` or any 'strict' options, as
  297. these turn off full support for `__float128`. These requirements also apply to the Intel compiler on Linux, for
  298. Intel on Windows you need to compile with `-Qoption,cpp,--extended_float_type -DBOOST_MATH_USE_FLOAT128` in order to
  299. activate 128-bit floating point support.]
  300. The `__float128` type is provided by the [@http://gcc.gnu.org/onlinedocs/libquadmath/ libquadmath library] on GCC or
  301. by Intel's FORTRAN library with Intel C++. They also provide a full set of `<cmath>` functions in `namespace std`.
  302. [h4 Using C __float128 quadmath type]
  303. [/quadmath_snprintf_1]
  304. The source code is at [@https://gcc.gnu.org/onlinedocs/gcc-9.1.0/libquadmath/quadmath_005fsnprintf.html#quadmath_005fsnprintf quadmath_snprintf.c].
  305. [h4 Using C++ `float128` quadmath type]
  306. For C++ programs, you will want to use the C++ type `float128`
  307. See example at [@../../example/cstdfloat_example.cpp cstdfloat_example.cpp].
  308. A typical invocation of the compiler is
  309. g++ -O3 -std=gnu++11 test.cpp -I/c/modular-boost -lquadmath -o test.exe
  310. [tip If you are trying to use the develop branch of Boost.Math, then make `-I/c/modular-boost/libs/math/include` the [*first] include directory.]
  311. g++ -O3 -std=gnu++11 test.cpp -I/c/modular-boost/libs/math/include -I/c/modular-boost -lquadmath -o test.exe
  312. [note So far, the only missing detail that we had noted was in trying to use `<typeinfo>`,
  313. for example for `std::cout << typeid<__float_128>.name();`.
  314. ``
  315. Link fails: undefined reference to typeinfo for __float128.
  316. ``
  317. See [@http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43622 GCC Bug 43622 - no C++ typeinfo for __float128].
  318. But this is reported (Marc Glisse 2015-04-04 ) fixed in GCC 5 (and above).
  319. For example, with GCC6.1.1 this works as expected to a [*mangled] string name, and output (if possible - not always).
  320. ``
  321. const std::type_info& tifu128 = typeid(__float128); // OK.
  322. //std::cout << tifu128.name() << std::endl; // On GCC, aborts (because not printable string).
  323. //std::cout << typeid(__float128).name() << std::endl; // Aborts - string name cannot be output.
  324. const std::type_info& tif128 = typeid(float128); // OK.
  325. std::cout << tif128.name() << std::endl; // OK.
  326. std::cout << typeid(float128).name() << std::endl; // OK.
  327. const std::type_info& tpi = typeid(pi1); // OK GCC 6.1.1 (from GCC 5 according to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43622)
  328. std::cout << tpi.name() << std::endl; // Output mangled name:
  329. // N5boost14multiprecision6numberINS0_8backends16float128_backendELNS0_26expression_template_optionE0EEE
  330. ``
  331. ] [/note]
  332. [section:overloading Overloading template functions with float128_t]
  333. An artifact of providing C++ standard library support for
  334. quadmath may mandate the inclusion of `<boost/cstdfloat.hpp>`
  335. [*before] the inclusion of other headers.
  336. Consider a function that calls `fabs(x)` and has previously injected `std::fabs()`
  337. into local scope via a `using` directive:
  338. template <class T>
  339. bool unsigned_compare(T a, T b)
  340. {
  341. using std::fabs;
  342. return fabs(a) == fabs(b);
  343. }
  344. In this function, the correct overload of `fabs` may be found via
  345. [@http://en.wikipedia.org/wiki/Argument-dependent_name_lookup argument-dependent-lookup (ADL)]
  346. or by calling one of the `std::fabs` overloads. There is a key difference between them
  347. however: an overload in the same namespace as T and found via ADL need ['[*not be defined at the
  348. time the function is declared]]. However, all the types declared in `<boost/cstdfloat.hpp>` are
  349. fundamental types, so for these types we are relying on finding an overload declared in namespace `std`.
  350. In that case however, ['[*all such overloads must be declared prior to the definition of function
  351. `unsigned_compare` otherwise they are not considered]].
  352. In the event that `<boost/cstdfloat.hpp>` has been included [*after] the
  353. definition of the above function, the correct overload of `fabs`, while present, is simply
  354. not considered as part of the overload set.
  355. So the compiler tries to downcast the `float128_t` argument first to
  356. `long double`, then to `double`, then to `float`;
  357. the compilation fails because the result is ambiguous.
  358. However the compiler error message will appear cruelly inscrutable,
  359. at an apparently irelevant line number and making no mention of `float128`:
  360. the word ['ambiguous] is the clue to what is wrong.
  361. Provided you `#include <boost/cstdfloat.hpp>` [*before] the inclusion
  362. of the any header containing generic floating point code (such as other
  363. Boost.Math headers, then the compiler
  364. will know about and use the `std::fabs(std::float128_t)`
  365. that we provide in `#include <boost/cstdfloat.hpp>`.
  366. [endsect]
  367. [section:exp_function Exponential function]
  368. There was a bug when using any quadmath `expq` function on GCC :
  369. [@http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60349 GCC bug #60349]
  370. caused by
  371. [@http://sourceforge.net/p/mingw-w64/bugs/368/ mingw-64 bug #368].
  372. To work round this defect, an alternative implementation of 128-bit exp
  373. was temporarily provided by `boost/cstdfloat.hpp`.
  374. The mingw bug was fixed at 2014-03-12 and GCC 6.1.1 now works as expected.
  375. [tip It is essential to *link* to the quadmath library, for example, in a b2/bjam file: `<linkflags>-lquadmath`].
  376. [endsect] [/section:exp_function exp function]
  377. [section:typeinfo `typeinfo`]
  378. For GCC 4.8.1 it was not yet possible to use `typeinfo` for `float_128` on GCC:
  379. see [@http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43622 GCC 43622].
  380. So this code (to display the mangled name)
  381. failed to link `undefined reference to typeinfo for __float128`
  382. std::cout << typeid(boost::float128_t).name() << std::endl;
  383. This prevent using the existing tests for Boost.Math distributions,
  384. (unless a few lines are commented out)
  385. and if a MACRO BOOST_MATH_INSTRUMENT controlling them is defined
  386. then some diagnostic displays in Boost.Math will not work.
  387. However this was only used for display purposes
  388. and could be commented out until this was fixed in GCC 5.
  389. [tip Not all managed names can be [*displayed] using `std::cout`.]
  390. [endsect] [/section:typeinfo `typeinfo`]
  391. [endsect] [/section:float128 Float128 type]
  392. [/ cstdfloat.qbk
  393. Copyright 2014 Christopher Kormanyos, John Maddock and Paul A. Bristow.
  394. Distributed under the Boost Software License, Version 1.0.
  395. (See accompanying file LICENSE_1_0.txt or copy at
  396. http://www.boost.org/LICENSE_1_0.txt).
  397. ]