Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / multiprecision / doc / numeric_limits_qbk.cpp
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 // https://doi.org/10.1109/IEEESTD.1985.82928
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