]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright Paul A. Bristow 2013 |
2 | ||
3 | // Use, modification and distribution are subject to the | |
4 | // Boost Software License, Version 1.0. | |
5 | // (See accompanying file LICENSE_1_0.txt | |
6 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | // Program to list all numeric_limits items for any type to a file in Quickbook format. | |
9 | ||
10 | // C standard http://www.open-std.org/jtc1/sc22/wg11/docs/n507.pdf | |
11 | // SC22/WG11 N507 DRAFT INTERNATIONAL ISO/IEC STANDARD WD 10967-1 | |
12 | // Information technology Language independent arithmetic Part 1: Integer and Floating point arithmetic | |
13 | ||
14 | /* E.3 C++ | |
15 | The programming language C++ is defined by ISO/IEC 14882:1998, Programming languages C++ [18]. | |
16 | An implementation should follow all the requirements of LIA-1 unless otherwise specified by | |
17 | this language binding. | |
18 | */ | |
19 | ||
20 | // http://754r.ucbtest.org/standards/754.pdf | |
21 | ||
22 | // http://www.cesura17.net/~will/Professional/Research/Papers/retrospective.pdf | |
23 | ||
24 | // http://www.exploringbinary.com/using-integers-to-check-a-floating-point-approximation/ | |
25 | ||
26 | // http://stackoverflow.com/questions/12466745/how-to-convert-float-to-doubleboth-stored-in-ieee-754-representation-without-loss | |
27 | ||
28 | ||
29 | #ifdef _MSC_VER | |
30 | # pragma warning (disable : 4127) // conditional expression is constant. | |
31 | # pragma warning (disable : 4100) // unreferenced formal parameter. | |
32 | #endif | |
33 | ||
34 | ||
35 | #include <iostream> | |
36 | #include <iomanip> | |
37 | #include <string> | |
38 | #include <sstream> | |
39 | #include <fstream> | |
40 | #include <limits> // numeric_limits | |
41 | ||
42 | #include <typeinfo> | |
43 | ||
44 | #include <boost/version.hpp> | |
45 | #include <boost/config.hpp> | |
46 | ||
47 | // May need extra includes for other types, for example: | |
48 | #include <boost/multiprecision/cpp_dec_float.hpp> // is decimal. | |
49 | #include <boost/multiprecision/cpp_bin_float.hpp> // is binary. | |
50 | ||
51 | ||
52 | // Assume that this will be run on MSVC to get the 32 or 64 bit info. | |
53 | #ifdef _WIN32 | |
54 | std::string bits32_64 = "32"; | |
55 | std::string filename = "numeric_limits_32_tables.qbk"; | |
56 | #else | |
57 | std::string bits32_64 = "64"; | |
58 | std::string filename = "numeric_limits_64_tables.qbk"; | |
59 | #endif | |
60 | ||
61 | #ifdef INT32_T_MAX | |
62 | int i = INT256_T_MAX; | |
63 | #endif | |
64 | ||
65 | std::array<std::string, 16> integer_type_names = | |
66 | { | |
67 | "bool", | |
68 | "char", | |
69 | "unsigned char", | |
70 | "char16_t", | |
71 | "char32_t", | |
72 | "short", | |
73 | "unsigned short", | |
74 | "int", | |
75 | "unsigned int", | |
76 | "long", | |
77 | "unsigned long", | |
78 | "long long", | |
79 | "unsigned long long", | |
80 | "int32_t", | |
81 | //"uint32_t", | |
82 | "int64_t", | |
83 | //"uint64_t", | |
84 | "int128_t", | |
85 | //"uint128_t" // Too big? | |
86 | //"int256_t", | |
87 | //"uint256_t" | |
88 | //"int512_t" | |
89 | }; | |
90 | ||
91 | std::array<std::string, 6> float_type_names = | |
92 | { | |
93 | "function", "float", "double", "long double", "cpp_dec_50", "cpp_bin_128" | |
94 | }; | |
95 | ||
96 | // Table headings for integer constants. | |
97 | std::array<std::string, 8> integer_constant_heads = | |
98 | { | |
99 | "type", "signed", "bound", "modulo", "round", "radix", "digits", "digits10", // "max_digits10" | |
100 | }; | |
101 | ||
102 | // Table headings for integer functions. | |
103 | std::array<std::string, 2> integer_function_heads = | |
104 | { | |
105 | "max", // "lowest", assumes is same for all integer types, so not worth listing. | |
106 | "min" | |
107 | }; | |
108 | ||
109 | // Table headings for float constants. | |
110 | std::array<std::string, 12> float_constant_heads = | |
111 | { | |
112 | "type", // "signed", "exact", "bound", // "modulo", | |
113 | "round", "radix", "digits", "digits10", "max_digits10", "min_exp", "min_exp10", "max_exp", "max_exp10", "tiny", "trap" | |
114 | }; | |
115 | ||
116 | // Table headings for float functions. | |
117 | std::array<std::string, 10> float_function_heads = | |
118 | { | |
119 | "function", "max", "lowest", "min", "eps", "round", "infinity", "NaN", "sig_NaN", "denorm_min" | |
120 | }; | |
121 | ||
122 | std::string versions() | |
123 | { // Build a string of info about Boost, platform, STL, etc. | |
124 | std::stringstream mess; | |
125 | //mess << "\n" << "Program:\n\" " __FILE__ << "\"\n"; // \n is mis-interpreted! | |
126 | mess << "\n" << "Program:\n numeric_limits_qbk.cpp \n"; | |
127 | #ifdef __TIMESTAMP__ | |
128 | mess << __TIMESTAMP__; | |
129 | #endif | |
130 | mess << "\nBuildInfo:\n" " Platform " << BOOST_PLATFORM; | |
131 | mess << "\n Compiler " BOOST_COMPILER; | |
132 | #ifdef _MSC_FULL_VER | |
133 | mess << "\n MSVC version "<< BOOST_STRINGIZE(_MSC_FULL_VER) << "."; | |
134 | #endif | |
135 | mess << "\n STL " BOOST_STDLIB; | |
136 | mess << "\n Boost version " << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100 << std::endl; | |
137 | return mess.str(); | |
138 | } // std::string versions() | |
139 | ||
140 | template <typename T> | |
141 | void out_round_style(std::ostream& os) | |
142 | { //! Send short string describing STD::round_style to stream os. | |
143 | // os << "Round style is "; | |
144 | if (std::numeric_limits<T>::round_style == std::round_indeterminate) | |
145 | { | |
146 | os << "indeterminate" ; | |
147 | } | |
148 | else if (std::numeric_limits<T>::round_style == std::round_toward_zero) | |
149 | { | |
150 | os << "to zero" ; | |
151 | } | |
152 | else if (std::numeric_limits<T>::round_style == std::round_to_nearest) | |
153 | { | |
154 | os << "to nearest" ; | |
155 | } | |
156 | else if (std::numeric_limits<T>::round_style == std::round_toward_infinity) | |
157 | { | |
158 | os << "to infin[]"; // Or << "to \u221E" << "to infinity" ; | |
159 | } | |
160 | else if (std::numeric_limits<T>::round_style == std::round_toward_neg_infinity) | |
161 | { | |
162 | os << "to -infin[]" ; | |
163 | } | |
164 | else | |
165 | { | |
166 | os << "undefined!"; | |
167 | std::cout << "std::numeric_limits<T>::round_style is undefined value!" << std::endl; | |
168 | } | |
169 | return; | |
170 | } // out_round_style(std::ostream& os); | |
171 | ||
172 | template<typename T> | |
173 | void integer_constants(std::string type_name, std::ostream& os) | |
174 | { //! Output a line of table integer constant values to ostream os. | |
175 | os << "\n[" | |
176 | "[" << type_name << "]" ; | |
177 | os << "[" << (std::numeric_limits<T>::is_signed ? "signed" : "unsigned") << "]" ; | |
178 | // Is always exact for integer types, so removed: | |
179 | // os << "[" << (std::numeric_limits<T>::is_exact ? "exact" : "inexact") << "]" ; | |
180 | os << "[" << (std::numeric_limits<T>::is_bounded ? "bound" : "unbounded") << "]" ; | |
181 | os << "[" << (std::numeric_limits<T>::is_modulo ? "modulo" : "no") << "]" ; | |
182 | os << "[" ; out_round_style<T>(os); os << "]" ; | |
183 | os << "[" << std::numeric_limits<T>::radix << "]" ; | |
184 | os << "[" << std::numeric_limits<T>::digits << "]" ; | |
185 | os << "[" << std::numeric_limits<T>::digits10 << "]" ; | |
186 | // Undefined for integers, so removed: | |
187 | // os << "[" << std::numeric_limits<T>::max_digits10 << "]" | |
188 | os << "]"; | |
189 | } // void integer_constants | |
190 | ||
191 | ||
192 | template<typename T> | |
193 | void float_constants(std::string type_name, std::ostream& os) | |
194 | { //! Output a row of table values to `ostream` os. | |
195 | os << "\n[" | |
196 | "[" << type_name << "]" ; | |
197 | //os << "[" << (std::numeric_limits<T>::is_signed ? "signed" : "unsigned") << "]" ; | |
198 | //os << "[" << (std::numeric_limits<T>::is_exact ? "exact" : "inexact") << "]" ; | |
199 | //os << "[" << (std::numeric_limits<T>::is_bounded ? "bound" : "no") << "]" ; | |
200 | // os << "[" << (std::numeric_limits<T>::is_modulo ? "modulo" : "no") << "]" ; | |
201 | os << "[" ; out_round_style<T>(os); os << "]" ; | |
202 | os << "[" << std::numeric_limits<T>::radix << "]" ; | |
203 | os << "[" << std::numeric_limits<T>::digits << "]" ; | |
204 | os << "[" << std::numeric_limits<T>::digits10 << "]" ; | |
205 | os << "[" << std::numeric_limits<T>::max_digits10 << "]"; | |
206 | os << "[" << std::numeric_limits<T>::min_exponent << "]" ; | |
207 | os << "[" << std::numeric_limits<T>::min_exponent10 << "]" ; | |
208 | os << "[" << std::numeric_limits<T>::max_exponent << "]" ; | |
209 | os << "[" << std::numeric_limits<T>::max_exponent10 << "]" ; | |
210 | os << "[" << (std::numeric_limits<T>::tinyness_before ? "tiny" : "no") << "]" ; | |
211 | os << "[" << (std::numeric_limits<T>::traps ? "traps" : "no") << "]" ; | |
212 | os << "]" "\n"; // end of row. | |
213 | } // void float_constants | |
214 | ||
215 | /* Types across and two functions down. | |
216 | ||
217 | template<typename T> | |
218 | void integer_functions(std::string type_name, std::ostream& os) | |
219 | { //! Output a line of table integer function values to `ostream` os. | |
220 | os << "\n[" | |
221 | "[" << type_name << "]" ; | |
222 | os << "[" << std::numeric_limits<T>::max() << "]" ; | |
223 | //os << "[" << std::numeric_limits<T>::lowest() << "]" ; always == min for integer types, | |
224 | // so removed to save space. | |
225 | os << "[" << std::numeric_limits<T>::min() << "]" | |
226 | "]"; | |
227 | } // void integer_functions | |
228 | ||
229 | */ | |
230 | ||
231 | // Types down and two (or three) functions across. | |
232 | template<typename T> | |
233 | void integer_functions(std::string type_name, std::ostream& os) | |
234 | { //! Output a line of table integer function values to `ostream` os. | |
235 | os << "\n[" // start of row. | |
236 | "[" << type_name << "]" ; | |
237 | os << "[" << std::numeric_limits<T>::max() << "]" ; | |
238 | // os << "[" << std::numeric_limits<T>::lowest() << "]" ; | |
239 | os << "[" << std::numeric_limits<T>::min() << "]" ; | |
240 | os << "]"; // end of row. | |
241 | } // void integer_functions | |
242 | ||
243 | ||
244 | template<typename T> | |
245 | void float_functions(std::string type_name, std::ostream& os) | |
246 | { //! Output a line of table float-point function values to `ostream` os. | |
247 | os << "\n[" // start of row. | |
248 | "[" << type_name << "]" ; | |
249 | os << "[" << std::numeric_limits<T>::max() << "]" ; | |
250 | os << "[" << std::numeric_limits<T>::lowest() << "]" ; | |
251 | os << "[" << std::numeric_limits<T>::min() << "]" | |
252 | os << "[" << std::numeric_limits<T>::epsilon() << "]" | |
253 | os << "[" << std::numeric_limits<T>::round_error() << "]" | |
254 | os << "[" << std::numeric_limits<T>::infinity() << "]" | |
255 | os << "[" << std::numeric_limits<T>::quiet_NaN() << "]" | |
256 | os << "[" << std::numeric_limits<T>::signaling_NaN() << "]" | |
257 | os << "[" << std::numeric_limits<T>::denorm_min() << "]" | |
258 | "]"; // end of row. | |
259 | } // void float_functions | |
260 | ||
261 | template<typename T> | |
262 | int numeric_limits_list(std::string description) | |
263 | {//! Output numeric_limits for numeric_limits<T>, for example `numeric_limits_list<bool>()`. | |
264 | // This is not used for Quickbook format. | |
265 | // std::cout << versions() << std::endl; | |
266 | ||
267 | std::cout << "\n" << description << "\n" << std::endl; // int, int64_t rather than full long typeid(T).name(). | |
268 | ||
269 | std::cout << "Type " << typeid(T).name() << " std::numeric_limits::<" << typeid(T).name() << ">\n" << std::endl; | |
270 | // ull long typeid(T).name() | |
271 | ||
272 | if (std::numeric_limits<T>::is_specialized == false) | |
273 | { | |
274 | std::cout << "type " << typeid(T).name() << " is not specialized for std::numeric_limits!" << std::endl; | |
275 | //return -1; | |
276 | } | |
277 | ||
278 | // Member constants. | |
279 | ||
280 | std::cout << (std::numeric_limits<T>::is_signed ? "is signed." : "unsigned.") << std::endl; | |
281 | std::cout << (std::numeric_limits<T>::is_integer ? "is integer." : "not integer (fixed or float-point).") << std::endl; | |
282 | std::cout << (std::numeric_limits<T>::is_exact ? "is exact." : "not exact.") << std::endl; | |
283 | std::cout << (std::numeric_limits<T>::has_infinity ? "has infinity." : "no infinity.") << std::endl; | |
284 | std::cout << (std::numeric_limits<T>::has_quiet_NaN ? "has quiet NaN." : "no quiet NaN.") << std::endl; | |
285 | std::cout << (std::numeric_limits<T>::has_signaling_NaN ? "has signaling NaN." : "no signaling NaN.") << std::endl; | |
286 | if (!std::numeric_limits<T>::is_integer) | |
287 | { // is floating_point | |
288 | std::cout << "Denorm style is " ; | |
289 | if (std::numeric_limits<T>::has_denorm == std::denorm_absent) | |
290 | { | |
291 | std::cout << "denorm_absent." << std::endl; | |
292 | } | |
293 | else if (std::numeric_limits<T>::has_denorm == std::denorm_present) | |
294 | { | |
295 | std::cout << "denorm_present." << std::endl; | |
296 | } | |
297 | else if (std::numeric_limits<T>::has_denorm == std::denorm_indeterminate) | |
298 | { | |
299 | std::cout << "denorm_indeterminate." << std::endl; | |
300 | } | |
301 | else | |
302 | { | |
303 | std::cout << "std::numeric_limits<T>::has_denorm unexpected value!" << std::endl; | |
304 | } | |
305 | ||
306 | std::cout << (std::numeric_limits<T>::has_denorm_loss ? "has denorm loss." : "no denorm loss.") << std::endl; | |
307 | // true if a loss of accuracy is detected as a denormalization loss, rather than an inexact result. | |
308 | ||
309 | std::cout << "Round style is "; | |
310 | if (std::numeric_limits<T>::round_style == std::round_indeterminate) | |
311 | { | |
312 | std::cout << "round_indeterminate!" << std::endl; | |
313 | } | |
314 | else if (std::numeric_limits<T>::round_style == std::round_toward_zero) | |
315 | { | |
316 | std::cout << "round_toward_zero." << std::endl; | |
317 | } | |
318 | else if (std::numeric_limits<T>::round_style == std::round_to_nearest) | |
319 | { | |
320 | std::cout << "round_to_nearest." << std::endl; | |
321 | } | |
322 | else if (std::numeric_limits<T>::round_style == std::round_toward_infinity) | |
323 | { | |
324 | std::cout << "round_toward_infinity." << std::endl; | |
325 | } | |
326 | else if (std::numeric_limits<T>::round_style == std::round_toward_neg_infinity) | |
327 | { | |
328 | std::cout << "round_toward_neg_infinity." << std::endl; | |
329 | } | |
330 | else | |
331 | { | |
332 | std::cout << "undefined value!" << std::endl; | |
333 | } | |
334 | ||
335 | } // is floating_point | |
336 | ||
337 | std::cout << (std::numeric_limits<T>::is_iec559 ? "is IEC599." : "not IEC599.") << std::endl; | |
338 | std::cout << (std::numeric_limits<T>::is_bounded ? "is bound." : "unbounded.") << std::endl; | |
339 | std::cout << (std::numeric_limits<T>::is_modulo ? "is modulo." : "no modulo.") << std::endl; | |
340 | std::cout << std::dec << "radix " << std::numeric_limits<T>::radix << std::endl; | |
341 | std::cout << "digits " << std::numeric_limits<T>::digits << std::endl; | |
342 | std::cout << "digits10 " << std::numeric_limits<T>::digits10 << std::endl; | |
343 | ||
344 | std::cout.precision(std::numeric_limits<T>::max_digits10); // Full precision for floating-point values like max, min ... | |
345 | ||
346 | std::cout << "max_digits10 " << std::numeric_limits<T>::max_digits10 << std::endl; | |
347 | std::cout << "min_exponent " << std::numeric_limits<T>::min_exponent << std::endl; | |
348 | std::cout << "min_exponent10 " << std::numeric_limits<T>::min_exponent10 << std::endl; | |
349 | std::cout << "max_exponent " << std::numeric_limits<T>::max_exponent << std::endl; | |
350 | std::cout << "max_exponent10 " << std::numeric_limits<T>::max_exponent10 << std::endl; | |
351 | ||
352 | std::cout << (std::numeric_limits<T>::tinyness_before ? "Can tiny values before rounding." : "no tinyness_before.") << std::endl; | |
353 | // true if the type can detect tiny values before rounding; false if it cannot. | |
354 | std::cout << (std::numeric_limits<T>::traps ? "traps" : "no trapping.") << std::endl; | |
355 | // Whether trapping that reports on arithmetic exceptions is implemented for a type. | |
356 | ||
357 | std::cout << "Member functions." << std::endl; | |
358 | // (assumes operator<< for type T is available). | |
359 | // If floating-point then hex format may not be available. | |
360 | ||
361 | std::cout << "max = " << std::numeric_limits<T>::max() << std::endl; | |
362 | //if (std::numeric_limits<T>::is_integer) | |
363 | //{ | |
364 | // std::cout << " = " << std::hex << std::numeric_limits<T>::max() << std::endl; | |
365 | //} | |
366 | ||
367 | std::cout << "lowest = " << std::dec << std::numeric_limits<T>::lowest() << std::endl; | |
368 | //if (std::numeric_limits<T>::is_integer) | |
369 | //{ | |
370 | // std::cout << " = " << std::hex << std::numeric_limits<T>::lowest() << std::endl; | |
371 | //} | |
372 | ||
373 | std::cout << "min = " << std::dec << std::numeric_limits<T>::min() << std::endl; | |
374 | //if (std::numeric_limits<T>::is_integer) | |
375 | //{ | |
376 | // std::cout << " = " << std::hex << std::numeric_limits<T>::min() << std::endl; | |
377 | //} | |
378 | ||
379 | std::cout << "epsilon = " << std::dec << std::numeric_limits<T>::epsilon() << std::endl; | |
380 | //if (std::numeric_limits<T>::is_integer) | |
381 | //{ | |
382 | // std::cout << " = " << std::hex << std::numeric_limits<T>::epsilon() << std::endl; | |
383 | //} | |
384 | // round_error is always zero for integer types. | |
385 | // round_error is usually 1/2 = (T)0.5 for floating-point types. | |
386 | // round_error is ? for fixed-point. | |
387 | std::cout << "round_error = " << std::numeric_limits<T>::round_error() << " ULP." << std::endl; | |
388 | ||
389 | std::cout << "infinity = " << std::dec << std::numeric_limits<T>::infinity() << std::endl; | |
390 | std::cout << " = " << std::hex << std::numeric_limits<T>::infinity() << std::endl; | |
391 | ||
392 | std::cout << "quiet_NaN = " << std::dec << std::numeric_limits<T>::quiet_NaN() << std::endl; | |
393 | std::cout << " = " << std::hex << std::numeric_limits<T>::quiet_NaN() << std::endl; | |
394 | ||
395 | std::cout << "signaling_NaN = " << std::dec << std::numeric_limits<T>::signaling_NaN() << std::endl; | |
396 | std::cout << " = " << std::hex << std::numeric_limits<T>::signaling_NaN() << std::endl; | |
397 | ||
398 | // Only meaningful if (std::numeric_limits<T>::has_denorm == std::denorm_present) | |
399 | // so might not bother to show if absent? | |
400 | std::cout << "denorm_min = " << std::numeric_limits<T>::denorm_min() << std::endl; | |
401 | std::cout << " = " << std::numeric_limits<T>::denorm_min() << std::endl; | |
402 | return 0; | |
403 | } | |
404 | ||
405 | int main() | |
406 | { | |
407 | ||
408 | ||
409 | ||
410 | try | |
411 | { | |
412 | using namespace boost::multiprecision; | |
413 | ||
414 | std::cout << versions() << std::endl; | |
415 | ||
416 | std::ofstream fout(filename, std::ios_base::out); | |
417 | if (!fout.is_open()) | |
418 | { | |
419 | std::cout << "Unable to open file " << filename << " for output.\n" << std::endl; | |
420 | return -1; // boost::EXIT_FAILURE; | |
421 | } | |
422 | fout << | |
423 | "[/""\n" | |
424 | "Copyright 2013 Paul A. Bristow.""\n" | |
425 | "Copyright 2013 John Maddock.""\n" | |
426 | "Distributed under the Boost Software License, Version 1.0.""\n" | |
427 | "(See accompanying file LICENSE_1_0.txt or copy at""\n" | |
428 | "http://www.boost.org/LICENSE_1_0.txt).""\n" | |
429 | "]""\n" | |
430 | << std::endl; | |
431 | ||
432 | fout << "[section:limits"<< bits32_64 << " Numeric limits for " << bits32_64 << "-bit platform]" << std::endl; | |
433 | ||
434 | // Output platform version info (32 or 64). | |
435 | fout << "These tables were generated using the following program and options:\n\n" | |
436 | "[pre""\n" | |
437 | << versions() | |
438 | << "]""\n" | |
439 | << std::endl; | |
440 | ||
441 | fout << "[table:integral_constants Integer types constants (`std::numeric_limits<T>::is_integer == true` && is_exact == true)" "\n" | |
442 | "["; | |
443 | ||
444 | for (size_t i = 0; i < integer_constant_heads.size(); i++) | |
445 | { // signed, bound, modulo ... | |
446 | fout << "[" << integer_constant_heads[i] << "]" ; | |
447 | } | |
448 | fout << "]"; | |
449 | ||
450 | integer_constants<bool>("bool", fout); | |
451 | integer_constants<char>("char", fout); | |
452 | integer_constants<unsigned char>("unsigned char", fout); | |
453 | integer_constants<char16_t>("char16_t", fout); | |
454 | integer_constants<char32_t>("char32_t", fout); | |
455 | integer_constants<short>("short", fout); | |
456 | integer_constants<unsigned short>("unsigned short", fout); | |
457 | integer_constants<int>("int", fout); | |
458 | integer_constants<unsigned int>("unsigned", fout); | |
459 | integer_constants<long>("long", fout); | |
460 | integer_constants<unsigned long>("unsigned long", fout); | |
461 | integer_constants<long long>("long long", fout); | |
462 | integer_constants<unsigned long long>("unsigned long long", fout); | |
463 | integer_constants<int32_t>("int32_t", fout); | |
464 | integer_constants<uint32_t>("uint32_t", fout); | |
465 | integer_constants<int64_t>("int64_t", fout); | |
466 | integer_constants<uint64_t>("uint64_t", fout); | |
467 | integer_constants<int128_t>("int128_t", fout); | |
468 | integer_constants<uint128_t>("uint128_t", fout); | |
469 | integer_constants<int256_t>("int256_t", fout); | |
470 | integer_constants<uint256_t>("uint256_t", fout); | |
471 | // integer_constants<int512_t>("int512_t", fout); | |
472 | //integer_constants<uint512_t>("uint512_t", fout); // Too big? | |
473 | integer_constants<cpp_int>("cpp_int", fout); | |
474 | ||
475 | fout << "\n]\n\n"; | |
476 | ||
477 | ||
478 | fout << "[table:integral_functions Integer types functions (`std::numeric_limits<T>::is_integer == true && std::numeric_limits<T>::min() == std::numeric_limits<T>::lowest()` )" "\n" | |
479 | "["; | |
480 | // Display types across the page, and 2 (or 3) functions as rows. | |
481 | ||
482 | fout << "[function]"; | |
483 | for (size_t i = 0; i < integer_function_heads.size(); i++) | |
484 | { | |
485 | fout << "[" << integer_function_heads[i] << "]" ; | |
486 | } | |
487 | fout << "]"; // end of headings. | |
488 | integer_functions<bool>("bool", fout); | |
489 | //integer_functions<char>("char", fout); // Need int value not char. | |
490 | fout << "\n[" // start of row. | |
491 | "[" << "char"<< "]" ; | |
492 | fout << "[" << static_cast<int>((std::numeric_limits<char>::max)()) << "]" ; | |
493 | // fout << "[" << (std::numeric_limits<T>::lowest)() << "]" ; | |
494 | fout << "[" << static_cast<int>((std::numeric_limits<char>::min)()) << "]" ; | |
495 | fout << "]"; // end of row. | |
496 | //integer_functions<unsigned char>("unsigned char", fout); // Need int value not char. | |
497 | fout << "\n[" // start of row. | |
498 | "[" << "unsigned char"<< "]" ; | |
499 | fout << "[" << static_cast<int>((std::numeric_limits<unsigned char>::max)()) << "]" ; | |
500 | // fout << "[" << std::numeric_limits<unsigned char>::lowest() << "]" ; | |
501 | fout << "[" << static_cast<int>(std::numeric_limits<unsigned char>::min()) << "]" ; | |
502 | fout << "]"; // end of row. | |
503 | ||
504 | integer_functions<char16_t>("char16_t", fout); | |
505 | integer_functions<char32_t>("char32_t", fout); | |
506 | integer_functions<short>("short", fout); | |
507 | integer_functions<unsigned short>("unsigned short", fout); | |
508 | integer_functions<int>("int", fout); | |
509 | integer_functions<unsigned int>("unsigned int", fout); | |
510 | integer_functions<long>("long", fout); | |
511 | integer_functions<unsigned long>("unsigned long", fout); | |
512 | integer_functions<long long>("long long", fout); | |
513 | integer_functions<unsigned long long>("unsigned long long", fout); | |
514 | integer_functions<int32_t>("int32_t", fout); | |
515 | integer_functions<int64_t>("int64_t", fout); | |
516 | integer_functions<int128_t>("int128_t", fout); | |
517 | fout << "]" "\n"; // end of table; | |
518 | ||
519 | ||
520 | //fout << "[[max]" | |
521 | // << "[" << std::numeric_limits<bool>::max() << "]" | |
522 | // << "[" << static_cast<int>(std::numeric_limits<char>::max()) << "]" | |
523 | // << "[" << static_cast<int>(std::numeric_limits<unsigned char>::max()) << "]" | |
524 | // << "[" << static_cast<int>(std::numeric_limits<char16_t>::max()) << "]" | |
525 | // << "[" << static_cast<int>(std::numeric_limits<char32_t>::max()) << "]" | |
526 | // << "[" << std::numeric_limits<short>::max() << "]" | |
527 | // << "[" << std::numeric_limits<unsigned short>::max() << "]" | |
528 | // << "[" << std::numeric_limits<int>::max() << "]" | |
529 | // << "[" << std::numeric_limits<unsigned int>::max() << "]" | |
530 | // << "[" << std::numeric_limits<long>::max() << "]" | |
531 | // << "[" << std::numeric_limits<unsigned long>::max() << "]" | |
532 | // << "[" << std::numeric_limits<long long>::max() << "]" | |
533 | // << "[" << std::numeric_limits<unsigned long long>::max() << "]" | |
534 | // << "[" << std::numeric_limits<int32_t>::max() << "]" | |
535 | // << "[" << std::numeric_limits<int64_t>::max() << "]" | |
536 | // << "[" << std::numeric_limits<int128_t>::max() << "]" | |
537 | // //<< "[" << std::numeric_limits<int256_t>::max() << "]" // too big? | |
538 | // //<< "[" << std::numeric_limits<int512_t>::max() << "]" // too big? | |
539 | // << "]" "\n"; | |
540 | ///* Assume lowest() is not useful as == min for all integer types. | |
541 | // */ | |
542 | ||
543 | //fout << "[[min]" | |
544 | // << "[" << std::numeric_limits<bool>::min() << "]" | |
545 | // << "[" << static_cast<int>(std::numeric_limits<char>::min()) << "]" | |
546 | // << "[" << static_cast<int>(std::numeric_limits<unsigned char>::min()) << "]" | |
547 | // << "[" << static_cast<int>(std::numeric_limits<char16_t>::min()) << "]" | |
548 | // << "[" << static_cast<int>(std::numeric_limits<char32_t>::min()) << "]" | |
549 | // << "[" << std::numeric_limits<short>::min() << "]" | |
550 | // << "[" << std::numeric_limits<unsigned short>::min() << "]" | |
551 | // << "[" << std::numeric_limits<int>::min() << "]" | |
552 | // << "[" << std::numeric_limits<unsigned int>::min() << "]" | |
553 | // << "[" << std::numeric_limits<long>::min() << "]" | |
554 | // << "[" << std::numeric_limits<unsigned long>::min() << "]" | |
555 | // << "[" << std::numeric_limits<long long>::min() << "]" | |
556 | // << "[" << std::numeric_limits<unsigned long long>::min() << "]" | |
557 | // << "[" << std::numeric_limits<int32_t>::min() << "]" | |
558 | // << "[" << std::numeric_limits<int64_t>::min() << "]" | |
559 | // << "[" << std::numeric_limits<int128_t>::min() << "]" | |
560 | // // << "[" << std::numeric_limits<int256_t>::min() << "]" // too big? | |
561 | // // << "[" << std::numeric_limits<int512_t>::min() << "]" // too big? | |
562 | // << "]""\n"; | |
563 | ||
564 | ||
565 | ||
566 | // Floating-point | |
567 | ||
568 | typedef number<cpp_dec_float<50> > cpp_dec_float_50; // 50 decimal digits. | |
569 | typedef number<cpp_bin_float<113> > bin_128bit_double_type; // == Binary rare long double. | |
570 | ||
571 | fout << | |
572 | //"[table:float_functions Floating-point types constants (`std::numeric_limits<T>::is_integer == false && std::numeric_limits<T>::is_modulo == false` )" "\n" | |
573 | "[table:float_functions Floating-point types constants (`std::numeric_limits<T>::is_integer==false && is_signed==true && is_modulo==false && is_exact==false && is_bound==true`)" "\n" | |
574 | "["; | |
575 | for (size_t i = 0; i < float_constant_heads.size(); i++) | |
576 | { | |
577 | fout << "[" << float_constant_heads[i] << "]" ; | |
578 | } | |
579 | fout << "]"; // end of headings. | |
580 | ||
581 | float_constants<float>("float", fout); | |
582 | float_constants<double>("double", fout); | |
583 | float_constants<long double>("long double", fout); | |
584 | float_constants<cpp_dec_float_50>("cpp_dec_float_50", fout); | |
585 | float_constants<bin_128bit_double_type>("bin_128bit_double_type", fout); | |
586 | fout << "]" "\n"; // end of table; | |
587 | ||
588 | fout << | |
589 | "[table:float_functions Floating-point types functions (`std::numeric_limits<T>::is_integer == false`)" "\n" | |
590 | "["; | |
591 | ||
592 | for (size_t i = 0; i < float_type_names.size(); i++) | |
593 | { | |
594 | fout << "[" << float_type_names[i] << "]" ; | |
595 | } | |
596 | fout << "]"; // end of headings. | |
597 | ||
598 | fout << "[[max]" | |
599 | << "[" << std::numeric_limits<float>::max() << "]" | |
600 | << "[" << std::numeric_limits<double>::max() << "]" | |
601 | //#if LDBL_MANT_DIG > DBL_MANT_DIG | |
602 | // Perhaps to test Long double is not just a duplication of double (but need change is headings too). | |
603 | << "[" << std::numeric_limits<long double>::max() << "]" | |
604 | //#endif | |
605 | << "[" << std::numeric_limits<cpp_dec_float_50>::max() << "]" | |
606 | << "[" << std::numeric_limits<bin_128bit_double_type >::max() << "]" | |
607 | << "]" "\n"; // end of row. | |
608 | ||
609 | fout << "[[min]" | |
610 | << "[" << std::numeric_limits<float>::min() << "]" | |
611 | << "[" << std::numeric_limits<double>::min() << "]" | |
612 | //#if LDBL_MANT_DIG > DBL_MANT_DIG | |
613 | // Long double is not just a duplication of double. | |
614 | << "[" << std::numeric_limits<long double>::min() << "]" | |
615 | //#endif | |
616 | << "[" << std::numeric_limits<cpp_dec_float_50 >::min() << "]" | |
617 | << "[" << std::numeric_limits<bin_128bit_double_type >::min() << "]" | |
618 | << "]" "\n"; // end of row. | |
619 | ||
620 | fout << "[[epsilon]" | |
621 | << "[" << std::numeric_limits<float>::epsilon() << "]" | |
622 | << "[" << std::numeric_limits<double>::epsilon() << "]" | |
623 | //#if LDBL_MANT_DIG > DBL_MANT_DIG | |
624 | // Long double is not just a duplication of double. | |
625 | << "[" << std::numeric_limits<long double>::epsilon() << "]" | |
626 | //#endif | |
627 | << "[" << std::numeric_limits<cpp_dec_float_50 >::epsilon() << "]" | |
628 | << "[" << std::numeric_limits<bin_128bit_double_type >::epsilon() << "]" | |
629 | << "]" "\n"; // end of row. | |
630 | ||
631 | fout << "[[round_error]" | |
632 | << "[" << std::numeric_limits<float>::round_error() << "]" | |
633 | << "[" << std::numeric_limits<double>::round_error() << "]" | |
634 | //#if LDBL_MANT_DIG > DBL_MANT_DIG | |
635 | // Long double is not just a duplication of double. | |
636 | << "[" << std::numeric_limits<long double>::round_error() << "]" | |
637 | //#endif | |
638 | << "[" << std::numeric_limits<cpp_dec_float_50 >::round_error() << "]" | |
639 | << "[" << std::numeric_limits<bin_128bit_double_type >::round_error() << "]" | |
640 | << "]" "\n"; // end of row. | |
641 | ||
642 | fout << "[[infinity]" | |
643 | << "[" << std::numeric_limits<float>::infinity() << "]" | |
644 | << "[" << std::numeric_limits<double>::infinity() << "]" | |
645 | //#if LDBL_MANT_DIG > DBL_MANT_DIG | |
646 | // Long double is not just a duplication of double. | |
647 | << "[" << std::numeric_limits<long double>::infinity() << "]" | |
648 | //#endif | |
649 | << "[" << std::numeric_limits<cpp_dec_float_50 >::infinity() << "]" | |
650 | << "[" << std::numeric_limits<bin_128bit_double_type >::infinity() << "]" | |
651 | << "]" "\n"; // end of row. | |
652 | ||
653 | fout << "[[quiet_NaN]" | |
654 | << "[" << std::numeric_limits<float>::quiet_NaN() << "]" | |
655 | << "[" << std::numeric_limits<double>::quiet_NaN() << "]" | |
656 | //#if LDBL_MANT_DIG > DBL_MANT_DIG | |
657 | // Long double is not just a duplication of double. | |
658 | << "[" << std::numeric_limits<long double>::quiet_NaN() << "]" | |
659 | //#endif | |
660 | << "[" << std::numeric_limits<cpp_dec_float_50 >::quiet_NaN() << "]" | |
661 | << "[" << std::numeric_limits<bin_128bit_double_type >::quiet_NaN() << "]" | |
662 | << "]" "\n"; // end of row. | |
663 | ||
664 | fout << "[[signaling_NaN]" | |
665 | << "[" << std::numeric_limits<float>::signaling_NaN() << "]" | |
666 | << "[" << std::numeric_limits<double>::signaling_NaN() << "]" | |
667 | //#if LDBL_MANT_DIG > DBL_MANT_DIG | |
668 | // Long double is not just a duplication of double. | |
669 | << "[" << std::numeric_limits<long double>::signaling_NaN() << "]" | |
670 | //#endif | |
671 | << "[" << std::numeric_limits<cpp_dec_float_50 >::signaling_NaN() << "]" | |
672 | << "[" << std::numeric_limits<bin_128bit_double_type >::signaling_NaN() << "]" | |
673 | << "]" "\n"; // end of row. | |
674 | ||
675 | fout << "[[denorm_min]" | |
676 | << "[" << std::numeric_limits<float>::denorm_min() << "]" | |
677 | << "[" << std::numeric_limits<double>::denorm_min() << "]" | |
678 | //#if LDBL_MANT_DIG > DBL_MANT_DIG | |
679 | // Long double is not just a duplication of double. | |
680 | << "[" << std::numeric_limits<long double>::denorm_min() << "]" | |
681 | //#endif | |
682 | << "[" << std::numeric_limits<cpp_dec_float_50 >::denorm_min() << "]" | |
683 | << "[" << std::numeric_limits<bin_128bit_double_type >::denorm_min() << "]" | |
684 | << "]" "\n"; // end of row. | |
685 | ||
686 | ||
687 | ||
688 | fout << "]" "\n"; // end of table; | |
689 | ||
690 | ||
691 | fout << "\n\n" | |
692 | "[endsect] [/section:limits32 Numeric limits for 32-bit platform]" "\n" << std::endl; | |
693 | ||
694 | ||
695 | ||
696 | fout.close(); | |
697 | } | |
698 | catch(std::exception ex) | |
699 | { | |
700 | std::cout << "exception thrown: " << ex.what() << std::endl; | |
701 | } | |
702 | ||
703 | ||
704 | } // int main() | |
705 | ||
706 | /* | |
707 | Description: Autorun "J:\Cpp\Misc\Debug\numeric_limits_qbk.exe" | |
708 | ||
709 | Program: I:\boost-sandbox\multiprecision.cpp_bin_float\libs\multiprecision\doc\numeric_limits_qbk.cpp | |
710 | Wed Aug 28 14:17:21 2013 | |
711 | BuildInfo: | |
712 | Platform Win32 | |
713 | Compiler Microsoft Visual C++ version 10.0 | |
714 | MSVC version 160040219. | |
715 | STL Dinkumware standard library version 520 | |
716 | Boost version 1.55.0 | |
717 | ||
718 | */ | |
719 |