]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [book Standardized Floating-Point typedefs for C and C++ |
2 | ||
3 | [quickbook 1.7] | |
4 | [copyright 2014 Christopher Kormanyos, John Maddock, Paul A. Bristow] | |
5 | [license | |
6 | Distributed under the Boost Software License, Version 1.0. | |
7 | (See accompanying file LICENSE_1_0.txt or copy at | |
8 | [@http://www.boost.org/LICENSE_1_0.txt]) | |
9 | ] | |
10 | [authors [Kormanyos, Christopher], [Maddock, John], [Bristow, Paul A.] ] | |
11 | [last-revision $Date$] | |
12 | [/version 1.8.3] | |
13 | ] | |
14 | ||
15 | [template tr1[] [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf Technical Report on C++ Library Extensions]] | |
16 | [template C99[] [@http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf C99 Standard ISO/IEC 9899:1999]] | |
17 | ||
18 | [def __gsl [@http://www.gnu.org/software/gsl/ GSL-1.9]] | |
19 | [def __glibc [@http://www.gnu.org/software/libc/ GNU C Lib]] | |
20 | [def __hpc [@http://docs.hp.com/en/B9106-90010/index.html HP-UX C Library]] | |
21 | [def __cephes [@http://www.netlib.org/cephes/ Cephes]] | |
22 | [def __NTL [@http://www.shoup.net/ntl/ NTL A Library for doing Number Theory]] | |
23 | [def __NTL_RR [@http://shoup.net/ntl/doc/RR.txt NTL::RR]] | |
24 | [def __NTL_quad_float [@http://shoup.net/ntl/doc/quad_float.txt NTL::quad_float]] | |
25 | [def __MPFR [@http://www.mpfr.org/ GNU MPFR library]] | |
26 | [def __GMP [@http://gmplib.org/ GNU Multiple Precision Arithmetic Library]] | |
27 | [def __multiprecision [@http://www.boost.org/doc/libs/1_53_0_beta1/libs/multiprecision/doc/html/index.html Boost.Multiprecision]] | |
28 | [def __cpp_dec_float [@http://www.boost.org/doc/libs/1_53_0_beta1/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html cpp_dec_float]] | |
29 | [def __R [@http://www.r-project.org/ The R Project for Statistical Computing]] | |
30 | [def __godfrey [link godfrey Godfrey]] | |
31 | [def __pugh [link pugh Pugh]] | |
32 | [def __NaN [@http://en.wikipedia.org/wiki/NaN NaN]] | |
33 | [def __errno [@http://en.wikipedia.org/wiki/Errno `::errno`]] | |
34 | [def __Mathworld [@http://mathworld.wolfram.com Wolfram MathWorld]] | |
35 | [def __Mathematica [@http://www.wolfram.com/products/mathematica/index.html Wolfram Mathematica]] | |
36 | [def __WolframAlpha [@http://www.wolframalpha.com/ Wolfram Alpha]] | |
37 | [def __TOMS748 [@http://portal.acm.org/citation.cfm?id=210111 TOMS Algorithm 748: enclosing zeros of continuous functions]] | |
38 | [def __TOMS910 [@http://portal.acm.org/citation.cfm?id=1916469 TOMS Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations]] | |
39 | [def __why_complements [link why_complements why complements?]] | |
40 | [def __complements [link math_toolkit.stat_tut.overview.complements complements]] | |
41 | [def __performance [link perf performance]] | |
42 | [def __building [link math_toolkit.building building libraries]] | |
43 | [def __e_float [@http://calgo.acm.org/910.zip e_float (TOMS Algorithm 910)]] | |
44 | [def __Abramowitz_Stegun M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions, NBS (1964)] | |
45 | [def __DMLF [@http://dlmf.nist.gov/ NIST Digital Library of Mathematical Functions]] | |
46 | [def __IEEE754 [@http://en.wikipedia.org/wiki/IEEE_floating_point IEEE_floating_point]] | |
47 | [def __N3626 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3626.pdf N3626]] | |
48 | [def __N1703 [@http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1703.pdf N1703]] | |
49 | ||
50 | [/ Some composite templates] | |
51 | [template super[x]'''<superscript>'''[x]'''</superscript>'''] | |
52 | [template sub[x]'''<subscript>'''[x]'''</subscript>'''] | |
53 | [template floor[x]'''⌊'''[x]'''⌋'''] | |
54 | [template floorlr[x][lfloor][x][rfloor]] | |
55 | [template ceil[x] '''⌈'''[x]'''⌉'''] | |
56 | ||
57 | [/template header_file[file] [@../../../../[file] [file]]] | |
58 | ||
59 | [note A printer-friendly PDF version of this manual is also available.] | |
60 | ||
61 | [section:overview Overview] | |
62 | ||
63 | The header `<boost/cstdfloat.hpp>` provides optional standardized | |
64 | floating-point `typedef`s having specified widths. | |
65 | These are useful for writing portable code because they | |
66 | should behave identically on all platforms. | |
67 | All `typedef`s are in `namespace boost`. | |
68 | ||
69 | The `typedef`s include `float16_t, float32_t, float64_t, float128_t`, | |
70 | their corresponding least and fast types, | |
71 | and the corresponding maximum-width type. | |
72 | The `typedef`s are based on underlying built-in types | |
73 | such as `float`, `double`, or `long double`, or based on other compiler-specific | |
74 | non-standardized types such as `__float128`. | |
75 | The underlying types of these typedef's must conform with | |
76 | the corresponding specifications of binary16, binary32, binary64, | |
77 | and binary128 in __IEEE754 floating-point format | |
78 | [@http://en.wikipedia.org/wiki/IEEE_floating_point]. | |
79 | ||
80 | The typedef's are based on __N3626 | |
81 | proposed for a new C++14 standard header `<cstdfloat>` and | |
82 | __N1703 proposed for a new C language standard header `<stdfloat.h>`. | |
83 | ||
84 | The 128-bit floating-point type, of great interest in scientific and | |
85 | numeric programming, is not required in the boost header, | |
86 | and may not be supplied for all platforms/compilers, because compiler | |
87 | support for a 128-bit floating-point type is not mandated by either | |
88 | the C standard or the C++ standard. | |
89 | ||
90 | The following code uses `<boost/cstdfloat.hpp>` in combination with | |
91 | `<boost/math/special_functions.hpp>` to compute a simplified | |
92 | version of the Jahnke-Emden-Lambda function. Here, we use | |
93 | a floating-point type with exactly 64 bits (i.e., `float64_t`). | |
94 | If we were to use, for instance, built-in `double`, | |
95 | then there would be no guarantee that the code would | |
96 | behave identically on all platforms. With `float64_t` from | |
97 | `<boost/cstdfloat.hpp>`, however, this is very likely. | |
98 | Using `float64_t`, we know that | |
99 | this code is portable and uses a floating-point type | |
100 | with approximately 15 decimal digits of precision. | |
101 | ||
102 | #include <cmath> | |
103 | #include <boost/cstdfloat.hpp> | |
104 | #include <boost/math/special_functions.hpp> | |
105 | ||
106 | boost::float64_t jahnke_emden_lambda(boost::float64_t v, boost::float64_t x) | |
107 | { | |
108 | const boost::float64_t gamma_v_plus_one = boost::math::tgamma(v + 1); | |
109 | const boost::float64_t x_half_pow_v = std::pow(x / 2, v); | |
110 | ||
111 | return gamma_v_plus_one * boost::math::cyl_bessel_j(x, v) / x_half_pow_v; | |
112 | } | |
113 | ||
114 | See `cstdfloat_test.cpp` for a more detailed test program. | |
115 | ||
116 | [endsect] [/section:overview Overview] | |
117 | ||
118 | [section:rationale Rationale] | |
119 | ||
120 | The implementation of `<boost/cstdfloat.hpp>` is designed to utilize `<float.h>`, | |
121 | defined in the 1989 C standard. The preprocessor is used to query certain | |
122 | preprocessor definitions in `<float.h>` such as FLT_MAX, DBL_MAX, etc. | |
123 | Based on the results of these queries, an attempt is made to automatically | |
124 | detect the presence of built-in floating-point types having specified widths. | |
125 | An unequivocal test regarding conformance with __IEEE754 (IEC599) based on | |
126 | [@ http://en.cppreference.com/w/cpp/types/numeric_limits/is_iec559 `std::numeric_limits<>::is_iec559`] | |
127 | is performed with `BOOST_STATIC_ASSERT`. | |
128 | ||
129 | The header `<boost/cstdfloat.hpp>` makes the standardized floating-point | |
130 | `typedef`s safely available in `namespace boost` without placing any names | |
131 | in `namespace std`. The intention is to complement rather than compete | |
132 | with a potential future C++ Standard Library that may contain these `typedef`s. | |
133 | Should some future C++ standard include `<stdfloat.h>` and `<cstdfloat>`, | |
134 | then `<boost/cstdfloat.hpp>` will continue to function, but will become redundant | |
135 | and may be safely deprecated. | |
136 | ||
137 | Because `<boost/cstdfloat.hpp>` is a boost header, its name conforms to the | |
138 | boost header naming conventions, not the C++ Standard Library header | |
139 | naming conventions. | |
140 | ||
141 | [note | |
142 | <boost/cstdfloat.hpp> [*cannot synthesize or create | |
143 | a `typedef` if the underlying type is not provided by the compiler]. | |
144 | For example, if a compiler does not have an underlying floating-point | |
145 | type with 128 bits (highly sought-after in scientific and numeric programming), | |
146 | then `float128_t` and its corresponding least and fast types are not | |
147 | provided by `<boost/cstdfloat.hpp`>.] | |
148 | ||
149 | [warning | |
150 | As an implementation artifact, certain C macro names from `<float.h>` | |
151 | may possibly be visible to users of `<boost/cstdfloat.hpp>`. | |
152 | Don't rely on using these macros; they are not part of any Boost-specified interface. | |
153 | Use `std::numeric_limits<>` for floating-point ranges, etc. instead.] | |
154 | ||
155 | [endsect] [/section:rationale Rationale] | |
156 | ||
157 | [section:exact_typdefs Exact-Width Floating-Point `typedef`s] | |
158 | ||
159 | The `typedef float#_t`, with # replaced by the width, designates a | |
160 | floating-point type of exactly # bits. For example `float32_t` denotes | |
161 | a single-precision floating-point type with approximately | |
162 | 7 decimal digits of precision (equivalent to binary32 in __IEEE754). | |
163 | ||
164 | Floating-point types specified in C and C++ are allowed to have | |
165 | implementation-specific widths and formats. | |
166 | However, if a platform supports underlying floating-point types | |
167 | (conformant with __IEEE754) with widths of 16, 32, 64, 128 bits, | |
168 | or any combination thereof, | |
169 | then `<boost/cstdfloat.hpp>` does provide the corresponding `typedef`s | |
170 | `float16_t, float32_t, float64_t, float128_t,` | |
171 | their corresponding least and fast types, | |
172 | and the corresponding maximum-width type | |
173 | ||
174 | The absence of `float128_t` is indicated by the macro `BOOST_NO_FLOAT128_T`. | |
175 | ||
176 | [endsect] [/section:exact_typdefs Exact-Width Floating-Point `typedef`s] | |
177 | ||
178 | ||
179 | [section:fastest_typdefs Fastest minimum-width floating-point `typedef`s] | |
180 | ||
181 | The `typedef float_least#_t`, with # replaced by the width, designates a | |
182 | floating-point type with a [*width of at least # bits], such that no | |
183 | floating-point type with lesser size has at least the specified width. | |
184 | Thus, `float_least32_t` denotes the smallest floating-point type with | |
185 | a width of at least 32 bits. | |
186 | ||
187 | Minimum-width floating-point types are provided for all existing | |
188 | exact-width floating-point types on a given platform. | |
189 | ||
190 | For example, if a platfrom supports `float32_t` and `float64_t`, | |
191 | then `float_least32_t` and `float_least64_t` will also be supported, etc. | |
192 | ||
193 | [endsect] [/section:fastest_typdefs Fastest minimum-width floating-point `typedef`s] | |
194 | ||
195 | [section:fastest_typdefs Fastest minimum-width floating-point `typedef`s] | |
196 | ||
197 | The typedef `float_fast#_t`, with # replaced by the width, designates | |
198 | the [*fastest] floating-point type with a width of at least # bits. | |
199 | ||
200 | There is no absolute guarantee that these types are the fastest for all purposes. | |
201 | In any case, however, they satisfy the precision and width requirements. | |
202 | ||
203 | Fastest minimum-width floating-point types are provided for all existing | |
204 | exact-width floating-point types on a given platform. | |
205 | ||
206 | For example, if a platform supports `float32_t` and `float64_t`, | |
207 | then `float_fast32_t` and `float_fast64_t` will also be supported, etc. | |
208 | ||
209 | [endsect] [/section:fastest_typdefs Fastest minimum-width floating-point `typedef`s] | |
210 | ||
211 | [section:greatest_typdefs Greatest-width floating-point typedef] | |
212 | ||
213 | The `typedef floatmax_t` designates a floating-point type capable of representing | |
214 | any value of any floating-point type in a given platform. | |
215 | ||
216 | The greatest-width typedef is provided for all platforms. | |
217 | ||
218 | [endsect] [/section:greatest_typdefs Greatest-width floating-point typedef] | |
219 | ||
220 | [section:macros Floating-Point Constant Macros] | |
221 | ||
222 | All macros of the type `BOOST_FLOAT16_C, BOOST_FLOAT32_C, BOOST_FLOAT64_C, | |
223 | BOOST_FLOAT128_C, BOOST_FLOATMAX_C` are always defined after inclusion of | |
224 | `<boost/cstdfloat.hpp>`. These allow floating-point constants of at | |
225 | least the specified width to be declared. | |
226 | ||
227 | For example: | |
228 | ||
229 | #include <boost/cstdfloat.hpp> | |
230 | ||
231 | // Declare Pythagoras' constant with approximately 7 decimal digits of precision. | |
232 | static const boost::float32_t pi = BOOST_FLOAT32_C(3.1415926536); | |
233 | ||
234 | // Declare the Euler-gamma constant with approximately 34 decimal digits of precision. | |
235 | static const boost::float128_t euler = BOOST_FLOAT128_C(0.57721566490153286060651209008240243104216); | |
236 | ||
237 | [endsect] [/section:macros Floating-Point Constant Macros] | |
238 | ||
239 | ||
240 | [/ cstdfloat.qbk | |
241 | Copyright 2014 Christopher Kormanyos, John Maddock and Paul A. Bristow. | |
242 | Distributed under the Boost Software License, Version 1.0. | |
243 | (See accompanying file LICENSE_1_0.txt or copy at | |
244 | http://www.boost.org/LICENSE_1_0.txt). | |
245 | ] | |
246 | ||
247 | ||
248 | ||
249 |