// exp().
// General includes.
#include "cl_sysdep.h"
// Specification.
#include "cln/float.h"
// Implementation.
#include "cl_F_tran.h"
#include "cln/float.h"
#include "cl_F.h"
#include "cln/lfloat.h"
#include "cl_LF.h"
#undef MAYBE_INLINE
#define MAYBE_INLINE inline
#include "cl_LF_minusp.cc"
#include "cl_LF_exponent.cc"
namespace cln {
// Division durch ln(2).
inline const cl_F_div_t cl_floor_ln2 (const cl_F& x)
{
// Bei 0<=x<1/2 kann man sofort q:=0 setzen.
if (!minusp(x) && (float_exponent(x) < 0))
return cl_F_div_t(0,x);
else
return floor2(x,cl_ln2(x));
}
inline const cl_LF_div_t cl_floor_ln2 (const cl_LF& x)
{
// Bei 0<=x<1/2 kann man sofort q:=0 setzen.
if (!minusp(x) && (float_exponent(x) < 0))
return cl_LF_div_t(0,x);
else
return floor2(x,The(cl_LF)(cl_ln2(x)));
}
const cl_F exp (const cl_F& x)
{
// Methode:
// d := (float-digits x),
// Genauigkeit um sqrt(d)+max(integer-length(e)) Bits erhöhen,
// (q,r) := (floor x ln(2))
// Ergebnis ist exp(q*ln(2)+r) = (scale-float exp(r) q).
// Rechengenauigkeit erhöhen und durch ln(2) dividieren:
if (longfloatp(x) && (TheLfloat(x)->len >= 84)) {
DeclareType(cl_LF,x);
var cl_LF_div_t q_r = cl_floor_ln2(extend(x,TheLfloat(x)->len+1));
var cl_I& q = q_r.quotient;
var cl_LF& r = q_r.remainder;
return cl_float(scale_float(expx_ratseries(r),q),x);
} else {
var cl_F_div_t q_r = cl_floor_ln2(cl_F_extendsqrtx(x));
var cl_I& q = q_r.quotient;
var cl_F& r = q_r.remainder;
return cl_float(scale_float(expx_naive(r),q),x);
}
}
} // namespace cln
syntax highlighted by Code2HTML, v. 0.9.1