Here is an example of my usage of long double, in this case the functions have a double precision interface, but the functions not directly available in double use long double internally:
field rng(const field& x,const field& y){
long double a = longdoublify(x);
long double b = longdoublify(y);
long double const m = powl(2,-64);
return (double)(next()*m*(b-a)+a);
}
const long double tau = 6.283185307179586477l;
field funct(const field& x,const field& y){
u16abstract a = stringify(x);
double b = doublify(y);
do{
if(a==sk("abs" )) {b=fabs(b);break;}
if(a==sk("sqrt")) {b=sqrt(b);break;}
if(a==sk("sin" )) {b=sinl(b*(tau/360.l));break;}
if(a==sk("cos" )) {b=cosl(b*(tau/360.l));break;}
if(a==sk("tan" )) {b=tanl(b*(tau/360.l));break;}
if(a==sk("asin")) {b=asinl(b)*(360.l/tau);break;}
if(a==sk("acos")) {b=acosl(b)*(360.l/tau);break;}
if(a==sk("atan")) {b=atanl(b)*(360.l/tau);break;}
if(a==sk("ln" )) {b=log(b);break;}
if(a==sk("log" )) {b=log10(b);break;}
if(a==sk("e ^" )) {b=exp(b);break;}
if(a==sk("10 ^")) {b=pow(10,b);break;}
}while(0);
return b;
}
So, for example, on a 32-bit ARM computer, where long double is double precision,
sinl(b*(tau/360.l)) is equivalent to
sin(b*(6.283185307179586/360)), whereas on Windows with Digital Mars, extended precision will be used. The intent is that the intermediate computations are native. With x87, extended precision is typically more native than double precision, so it makes sense to use long double as the native type, however, when long double is unnative, internal computations can slow down the program functions.