#include <float.h>
#include "math.h"
#include "math_private.h"
#include "k_log.h"
static const double
two54 = 1.80143985094819840000e+16,
ivln10hi = 4.34294481878168880939e-01,
ivln10lo = 2.50829467116452752298e-11,
log10_2hi = 3.01029995663611771306e-01,
log10_2lo = 3.69423907715893078616e-13;
static const double zero = 0.0;
static volatile double vzero = 0.0;
double
log10(double x)
{
double f,hfsq,hi,lo,r,val_hi,val_lo,w,y,y2;
int32_t i,k,hx;
u_int32_t lx;
EXTRACT_WORDS(hx,lx,x);
k=0;
if (hx < 0x00100000) {
if (((hx&0x7fffffff)|lx)==0)
return -two54/vzero;
if (hx<0) return (x-x)/zero;
k -= 54; x *= two54;
GET_HIGH_WORD(hx,x);
}
if (hx >= 0x7ff00000) return x+x;
if (hx == 0x3ff00000 && lx == 0)
return zero;
k += (hx>>20)-1023;
hx &= 0x000fffff;
i = (hx+0x95f64)&0x100000;
SET_HIGH_WORD(x,hx|(i^0x3ff00000));
k += (i>>20);
y = (double)k;
f = x - 1.0;
hfsq = 0.5*f*f;
r = k_log1p(f);
hi = f - hfsq;
SET_LOW_WORD(hi,0);
lo = (f - hi) - hfsq + r;
val_hi = hi*ivln10hi;
y2 = y*log10_2hi;
val_lo = y*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi;
w = y2 + val_hi;
val_lo += (y2 - w) + val_hi;
val_hi = w;
return val_lo + val_hi;
}
#if (LDBL_MANT_DIG == 53)
__weak_reference(log10, log10l);
#endif