#ifndef DOUBLE_EXTRAS_H
#define DOUBLE_EXTRAS_H
#ifdef DOUBLE_EXTRAS_INLINES_C
#define DOUBLE_EXTRAS_INLINE
#else
#define DOUBLE_EXTRAS_INLINE static inline
#endif
#include <stdint.h>
#include <math.h>
#include "flint.h"
#ifdef __cplusplus
extern "C" {
#endif
#define D_BITS 53
#define D_EPS 2.2204460492503130808e-16
#define D_INF HUGE_VAL
#define D_NAN (HUGE_VAL - HUGE_VAL)
double d_randtest(flint_rand_t state);
double d_randtest_signed(flint_rand_t state, slong minexp, slong maxexp);
double d_randtest_special(flint_rand_t state, slong minexp, slong maxexp);
DOUBLE_EXTRAS_INLINE
double d_polyval(const double * poly, int len, double x)
{
double t;
int i;
for (t = poly[len-1], i = len-2; i >= 0; i--)
t = poly[i] + x * t;
return t;
}
double d_lambertw(double x);
DOUBLE_EXTRAS_INLINE
int d_is_nan(double x)
{
return x != x;
}
double d_log2(double x);
typedef union
{
double f;
uint64_t i;
}
double_uint64_u;
#define D_MIN_NORMAL_EXPONENT -1022
#define D_MAX_NORMAL_EXPONENT 1023
#define D_EXPONENT_BIAS 1023
#define D_EXPONENT_SHIFT 52
FLINT_FORCE_INLINE double d_mul_2exp_inrange(double x, int i)
{
FLINT_ASSERT(i >= D_MIN_NORMAL_EXPONENT && i <= D_MAX_NORMAL_EXPONENT);
double_uint64_u u;
u.i = ((uint64_t) (i + D_EXPONENT_BIAS)) << D_EXPONENT_SHIFT;
return x * u.f;
}
FLINT_FORCE_INLINE double d_mul_2exp_inrange2(double x, int i)
{
FLINT_ASSERT(i >= D_MIN_NORMAL_EXPONENT && i <= D_MAX_NORMAL_EXPONENT);
FLINT_ASSERT(x != 0);
double_uint64_u u;
u.f = x;
u.i += ((uint64_t) i) << D_EXPONENT_SHIFT;
return u.f;
}
FLINT_FORCE_INLINE double d_mul_2exp(double x, int i)
{
if (i >= D_MIN_NORMAL_EXPONENT && i <= D_MAX_NORMAL_EXPONENT)
return d_mul_2exp_inrange(x, i);
else
return ldexp(x, i);
}
#ifdef __cplusplus
}
#endif
#endif