#include <math.h>
#include <stdint.h>
#ifdef ARMLIBM_SET_FLAGS
#include "required_arithmetic.h"
double logb( double x )
{
union{ double d; uint64_t u;}u = {x};
u.u &= 0x7fffffffffffffffULL;
int32_t exp = (int32_t) (u.u >> 52);
if( __builtin_expect( (uint32_t) exp - 1U >= 2046, 0 ) )
{ if( 0.0 == x )
return required_divide_double( -1.0, 0.0 );
if( x != x )
return x + x;
if( u.u == 0x7ff0000000000000ULL )
return __builtin_inf();
u.u |= 0x3ff0000000000000ULL;
u.d -= 1.0;
exp = (int32_t) (u.u >> 52);
return (double) (exp - (1023+1022));
}
return (double) (exp - 1023);
}
#else
double logb( double x )
{
union{ double d; uint64_t u;}u = {x};
u.u &= 0x7fffffffffffffffULL;
int32_t exp = (int32_t) (u.u >> 52);
if( __builtin_expect( (uint32_t) exp - 1U >= 2046, 0 ) )
{ if( 0.0 == x )
return -__builtin_inf();
if( x != x )
return x + x;
if( u.u == 0x7ff0000000000000ULL )
return __builtin_inf();
u.u |= 0x3ff0000000000000ULL;
u.d -= 1.0;
exp = (int32_t) (u.u >> 52);
return (double) (exp - (1023+1022));
}
return (double) (exp - 1023);
}
#endif