 Boost :

From: Paul A. Bristow (pbristow_at_[hidden])
Date: 2001-03-26 17:39:32

I have confirmed that this also works using MSVC++ 6 thus

// builtin_constants.h"

template<class T>
struct mathconst
{
static const T pi() {
long double x;
// Assembler insert to get floating point constants.
//#if (defined(__i386__) || defined(__i486__) || defined(__i586__))
// Using Intel X86 Floating Point
#if (_MSC_VER >1000)
// Compiling with Microsoft VS
__asm
{
fldpi
fstp x
}
#endif // _MSC_VER
// Compiling with Linux gcc
#ifdef __GNUC__
__asm__("fldpi" : "=t" (x));
#endif // __GNUC__
// What about others?
//#endif

return x;
}
};

Builtin math constants.cpp

#include <iostream>
#include <iomanip> // for setprecision
#include <limits> // for numeric_limits

#include "builtin_constants.h" // Uses X86 fldpi instruction.

using std::cout;
using std::endl;
using std::setprecision;

const long double Knuth_pi = 3.1415926535897932384626433832795028841972L; //
pi

int main()
{
cout << "Test " << __FILE__ << ' ' << __TIMESTAMP__ << endl;

double myPi = mathconst<double>::pi();

cout << "myPi as double (default precision 6 decimal digits) is " << myPi
<< endl;

cout << setprecision(std::numeric_limits<double>::digits10 + 2);
// Ensure all significant digits and two noisy digits are displayed.

cout << "myPi as double (all significant digits and two noisy) is " <<
mathconst<double>::pi() << endl;

std::cout << "mathconst<long double>::pi() " << mathconst<long
double>::pi() << std::endl;
std::cout << "Knuth_pi " << Knuth_pi << std::endl;
std::cout << "FP pi - Knuth_pi = " << Knuth_pi - mathconst<long
double>::pi() << std::endl;

return 0;
}

/* Output is

Test J:\Cpp\constants\Builtin_constants\builtin_constants.cpp Mon Mar 26
23:28:03
2001
myPi as double (default precision 6 decimal digits) is 3.14159
myPi as double (all significant digits and two noisy) is 3.1415926535897931
mathconst<long double>::pi() 3.1415926535897931
Knuth_pi 3.1415926535897931
FP pi - Knuth_pi = 0
Press any key to continue

*/

But I'm not sure what this tells us because precision may well be reduced to
53 bits double anyway
by the comparison. (Or does Windows make it work in 53 bit mode anyway?
(See Victor Shoup's note)

There are only a handle of X86 builtin constants anyway, and once one has
calculated pi*pi
the NTL quad_float calculated ones will be ore accurate anyway.

So I accept that there are potential better constants, but potential
problems too, so I simply propose to document these and use the calculated
ones.

Paul

> -----Original Message-----
> From: jmaurer [mailto:jmaurer]On Behalf Of Jens Maurer
> Sent: Monday, February 12, 2001 7:44 PM
> To: boost_at_[hidden]
> Subject: Re: [boost] Re: Math Constants
>
>
> k.hagan_at_[hidden] wrote:
> >
> > On the subject of providing constants in float, double and long
> > double flavours...
> >
> > 1 x86 family processors have built-in constants for pi and several
> > logarithms which are accurate to 66 bits.
>
> I've tried this with gcc on Linux:
>
> #include <iostream>
>
> template<class T>
> struct mathconst
> {
> static const T pi() {
> long double x;
> __asm__("fldpi" : "=t" (x));
> return x;
> }
> };
>
> int main()
> {
> std::cout << mathconst<long double>::pi()*2.5 << std::endl;
> }
>
>
> Looking at the assembler output, this looks fine and does what we
> want. However, using mathconst<double> instead of mathconst<long double>
> makes gcc store and re-load the value, possibly to get it adequately
> rounded. You can get around that in the "double" case by declaring
> "x" of type "double" instead.
>
> It seems that our current discussion does not preclude the use of
> built-in constants.
>
> Jens Maurer
>
>
>
>
>
>
>