On 30/04/2016 20:10, Cooper, Bridgette R D wrote:
Thanks John,
That seems to have worked for sqrt(pi). I'm also pretty new to c++ (I mostly code in fortran) which is probably where a lot of my confusions lie. I don't understand why I don't get the right answer with the declaration of pie I had before. In the real code I want to write I use sqrt of a float128 a lot and I want to be sure I am definitely not loosing precision as my overall calculation is extremely sensitive to precision. So how should I be declaring variables? I notice you had __float128. Does this do something different than just writing float128? I was already using using namespace boost::multi precision.
Without seeing your code, I can't say where you went wrong, but in general: * Make sure you declare variables with the correct type - float128 in your case. * Make sure you declare literals with the correct suffix - otherwise they'll be treated as type double - so make sure they have a Q suffix in your case. * All the std lib functions, plus all the constants, and special functions from Boost.Math should then just work. * Make sure std lib functions are called unqualified so that the correct overload is found via ADL, ie sqrt(variable) not std::sqrt(variable). * In general, try not to reinvent stuff - using constants from Boost.Math is probably less error prone than declaring your own, likewise the special functions etc. Now for the __float128/float128 confusion: __float128 is the compiler supplied hardware type, it's an extension to C++ and there is only minimal support for it in normal C++ (no IO streams or numeric_limits support, function names in libquadmath all have different names to the std ones etc.) So you can program that type directly but it's harder work. Type float128 is a thin wrapper around __float128 and makes it C++ and generic code friendly. Another example: using namespace boost::multiprecision; float128 pi1 = boost::math::constants::pi<float128>(); // returns constant of type float128 float128 pi2 = boost::math::constants::pi<__float128>(); // constant of type __float128 gets converted to float128 on the assignment float128 pi3 = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348Q; // DIY constant std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << sqrt(pi1) << std::endl; std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << sqrt(pi2) << std::endl; std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << sqrt(pi3) << std::endl; // compare to ready rolled constant from Boost.Math: std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << boost::math::constants::root_pi<float128>() << std::endl; Outputs: 1.77245385090551602729816748334114514 1.77245385090551602729816748334114514 1.77245385090551602729816748334114514 1.77245385090551602729816748334114514 Note that the casts within the sqrt call aren't needed since all the variables are the correct type to begin with. HTH, John.
________________________________________ From: Boost-users
on behalf of John Maddock Sent: Saturday, April 30, 2016 7:25:27 PM To: boost-users@lists.boost.org Subject: Re: [Boost-users] boost/multiprecision/float128 On 30/04/2016 18:38, Cooper, Bridgette R D wrote:
Hi Paul,
For a moment I thought that worked. It certainly does for log(2). I distinctly get two different values (with the first giving the "correct" value) if I try:
std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << log(float128(2.q)) << std::endl;
std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << log(2.q) << std::endl;
However, this isn't true for sqrt still. I checked by calculating the sqrt(pi) and comparing to
https://github.com/ned14/boost-trunk/blob/master/libs/multiprecision/test/te...
std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << sqrt(float128(pie)) << std::endl;
std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << sqrt(pie) << std::endl;
These two lines give me identical results and again only match the first 16 digits.
pie is defined as float128 and I copy/pasted the 100 digit value from the same test_sqrt.cpp given above.
I suspect an error in your declaration of pie, using this:
using namespace boost::multiprecision; __float128 pie = boost::math::constants::pi<__float128>(); std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << sqrt(float128(pie)) << std::endl; std::cout << std::setprecision(std::numeric_limits<float128>::max_digits10) << sqrt(pie) << std::endl;
I see as output:
1.77245385090551602729816748334114514 1.77245385090551588191942755656782538
John. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users