|
Boost Users : |
Subject: Re: [Boost-users] boost/multiprecision/float128
From: John Maddock (jz.maddock_at_[hidden])
Date: 2016-05-01 03:58:49
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 <boost-users-bounces_at_[hidden]> on behalf of John Maddock <jz.maddock_at_[hidden]>
> Sent: Saturday, April 30, 2016 7:25:27 PM
> To: boost-users_at_[hidden]
> 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/test_sqrt.cpp
>>
>>
>> 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_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net