diff --git a/example/cstdfloat_example.cpp b/example/cstdfloat_example.cpp index 0a837ed66..45e83b3fb 100644 --- a/example/cstdfloat_example.cpp +++ b/example/cstdfloat_example.cpp @@ -6,8 +6,6 @@ // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -/* - /*[cstdfloat_example_1 `This example shows use of a specified-width floating-point typedef to evaluate a moderately complex math function using @@ -17,7 +15,7 @@ about 15 decimal digits `std::numeric_limits::digits10`, The Jahnke Emden lambda function is described at -Weisstein, Eric W. "Lambda Function." From MathWorld--A Wolfram Web Resource. +Weisstein, Eric W. "Lambda Function." From MathWorld--A Wolfram Web Resource. http://mathworld.wolfram.com/LambdaFunction.html E. Jahnke and F. Emde, "Tables of Functions with Formulae and Curves," @@ -32,6 +30,32 @@ Dover, New York, 4th ed., (1945), pp. 180-188. #include #include +/*! +Function max_digits10 +Returns maximum number of possibly significant decimal digits for a floating-point type FPT, +even for older compilers/standard libraries that +lack support for std::numeric_limits::max_digits10, +when the Kahan formula is used instead. +Also provides the correct result for Visual Studio 2010 where the value provided for float is wrong. +*/ +namespace boost +{ +template +int max_digits10() +{ +// Since max_digits10 is not defined (or wrong) on older systems, define a local max_digits10. + // Usage: int m = max_digits10(); + const int m = +#if (defined BOOST_NO_CXX11_NUMERIC_LIMITS) || (_MSC_VER == 1600) // is wrongly 8 not 9 for VS2010. + 2 + std::numeric_limits::digits * 3010/10000; +#else + std::numeric_limits::max_digits10; +#endif + return m; +} +} // namespace boost + + boost::float64_t jahnke_emden_lambda(boost::float64_t v, boost::float64_t x) { const boost::float64_t gamma_v_plus_one = boost::math::tgamma(v + 1); @@ -42,28 +66,142 @@ boost::float64_t jahnke_emden_lambda(boost::float64_t v, boost::float64_t x) int main() { + std::cout.setf(std::ios::showpoint); // show all significant trailing zeros. + + long double p = 1.L; + //std::cout.precision(std::numeric_limits::digits10); + + std::cout << "pi = " << p << std::endl; + /*[cstdfloat_example_2 `To ensure that all possibly significant digits including trailing zeros are shown. */ std::cout.precision(std::numeric_limits::max_digits10); - std::cout.setf(std::ios::showpoint); // show all significant trailing zeros. try { // Always use try'n'catch blocks to ensure any error messages are available. // Evaluate a sample of the lambda function: boost::float64_t v = 1.; boost::float64_t x = 1.; - + std::cout << jahnke_emden_lambda(v, x) << std::endl; // 0.88010117148986700 //] [/cstdfloat_example_2] for (int i = 0; i < 10; i++) { - std::cout << std::setprecision(2) << boost::float64_t(i) << ' ' + std::cout << std::setprecision(2) << boost::float64_t(i) << ' ' << std::setprecision(std::numeric_limits::max_digits10) - << jahnke_emden_lambda(boost::float64_t(i), v) << std::endl; // + << jahnke_emden_lambda(boost::float64_t(i), v) << std::endl; // } + std::cout << "Floating-point type long double is available." << std::endl; + std::cout << " std::numeric_limits::digits10 == " + << std::numeric_limits::digits10 << std::endl; + std::cout << " std::numeric_limits::max_digits10 == " + << std::numeric_limits::max_digits10 << std::endl; // 21 + + long double p = boost::math::constants::pi(); + std::cout.precision(std::numeric_limits::digits10); + + std::cout << "pi = " << p << std::endl; + + + + // http://www.boost.org/doc/libs/1_54_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/float128.html + + +#ifdef BOOST_FLOAT16_C + std::cout << "Floating-point type boost::float16_t is available." << std::endl; +#else + std::cout << "Floating-point type boost::float16_t is NOT available." << std::endl; +#endif +#ifdef BOOST_FLOAT32_C + std::cout << "Floating-point type boost::float32_t is available." << std::endl; + std::cout << " std::numeric_limits::digits10 == " + << std::numeric_limits::digits10 << std::endl; + std::cout << " std::numeric_limits::max_digits10 == " + << std::numeric_limits::max_digits10 << std::endl; +#else + std::cout << "Floating-point type boost::float32_t is NOT available." << std::endl; +#endif +#ifdef BOOST_FLOAT64_C + std::cout << "Floating-point type boost::float64_t is available." << std::endl; + std::cout << " std::numeric_limits::digits10 == " + << std::numeric_limits::digits10 << std::endl; + std::cout << " std::numeric_limits::max_digits10 == " + << std::numeric_limits::max_digits10 << std::endl; + +#else + std::cout << "Floating-point type boost::float64_t is NOT available." << std::endl; +#endif +#ifdef BOOST_FLOAT80_C + std::cout << "Floating-point type boost::float80_t is available." << std::endl; + std::cout << " std::numeric_limits::digits10 == " + << std::numeric_limits::digits10 << std::endl; + std::cout << " std::numeric_limits::max_digits10 == " + << std::numeric_limits::max_digits10 << std::endl; + +#else + std::cout << "Floating-point type boost::float80_t is NOT available." << std::endl; + +#endif +#ifdef BOOST_FLOAT128_C + std::cout << "Floating-point type boost::float128_t is available." << std::endl; + std::cout << " std::numeric_limits::digits10 == " + << std::numeric_limits::digits10 << std::endl; + std::cout << " std::numeric_limits::max_digits10 == " + << std::numeric_limits::max_digits10 << std::endl; +#else + std::cout << "Floating-point type boost::float128_t is NOT available." << std::endl; +#endif + +// Show some constants that depend on the available type. +#ifdef BOOST_FLOAT16_C + std::cout.precision(boost::max_digits10()); // Show all significant decimal digits, + std::cout.setf(std::ios::showpoint); // including all significant trailing zeros. + + std::cout << "BOOST_FLOAT16_C(123.456789012345678901234567890) = " + << BOOST_FLOAT16_C(123.456789012345678901234567890) << std::endl; + // BOOST_FLOAT16_C(123.456789012345678901234567890) = 123.45678901234568 +#endif + +#ifdef BOOST_FLOAT32_C + std::cout.precision(boost::max_digits10()); // Show all significant decimal digits, + std::cout.setf(std::ios::showpoint); // including all significant trailing zeros. + + + std::cout << "BOOST_FLOAT32_C(123.456789012345678901234567890) = " + << BOOST_FLOAT32_C(123.456789012345678901234567890) << std::endl; + // BOOST_FLOAT32_C(123.456789012345678901234567890) = 123.456787 + +#endif + +#ifdef BOOST_FLOAT64_C + std::cout.precision(boost::max_digits10()); // Show all significant decimal digits, + std::cout.setf(std::ios::showpoint); // including all significant trailing zeros. + + std::cout << "BOOST_FLOAT64_C(123.456789012345678901234567890) = " + << BOOST_FLOAT64_C(123.456789012345678901234567890) << std::endl; + // BOOST_FLOAT64_C(123.456789012345678901234567890) = 123.45678901234568 +#endif + +#ifdef BOOST_FLOAT80_C + std::cout.precision(boost::max_digits10()); // Show all significant decimal digits, + std::cout.setf(std::ios::showpoint); // including all significant trailing zeros. + + std::cout << "BOOST_FLOAT80_C(123.456789012345678901234567890) = " + << BOOST_FLOAT80_C(123.456789012345678901234567890) << std::endl; + // BOOST_FLOAT80_C(123.456789012345678901234567890) = 123.456789012345678901234567890000000000000000 +#endif + +#ifdef BOOST_FLOAT128_C + std::cout.precision(boost::max_digits10()); // Show all significant decimal digits, + std::cout.setf(std::ios::showpoint); // including all significant trailing zeros. + + std::cout << "BOOST_FLOAT128_C(123.456789012345678901234567890) = " + << BOOST_FLOAT128_C(123.456789012345678901234567890) << std::endl; + // BOOST_FLOAT128_C(123.456789012345678901234567890) = 123.456789012345678901234567890000000000000000000 +#endif } catch (std::exception ex) { @@ -75,18 +213,29 @@ int main() /* [cstdfloat_output - 1.0000000000000000 - 0.88010117148986700 - 0.00 0.00000000000000000 - 1.0 0.88010117148986700 - 2.0 4.6137984620549854 - 3.0 16.274830009244948 - 4.0 -25.360637961042869 - 5.0 -1257.9038883512258 - 6.0 -12749.592182518225 - 7.0 -3020.9830849309396 - 8.0 2421897.6013183575 - 9.0 45577595.449204892 +0.88010117148986700 +0.00 0.00000000000000000 +1.0 0.88010117148986700 +2.0 4.6137984620549872 +3.0 16.274830009244951 +4.0 -25.360637961042869 +5.0 -1257.9038883512264 +6.0 -12749.592182518225 +7.0 -3020.9830849309437 +8.0 2421897.6013183584 +9.0 45577595.449204877 +Floating-point type boost::float16_t is NOT available. +Floating-point type boost::float32_t is available. + std::numeric_limits::digits10 == 6 + std::numeric_limits::max_digits10 == 9 +Floating-point type boost::float64_t is available. + std::numeric_limits::digits10 == 15 + std::numeric_limits::max_digits10 == 17 +Floating-point type boost::float80_t is NOT available. +Floating-point type boost::float128_t is NOT available. +BOOST_FLOAT32_C(123.456789012345678901234567890) = 123.456787 +BOOST_FLOAT64_C(123.456789012345678901234567890) = 123.45678901234568 + ] [/cstdfloat_output]