造轮子之math.h
最近自己实现了math.h中的一些函数, 目的还是为了熟悉一些原理性的知识, 虽然很多函数都有直接对应的硬件指令了…
#define LLMAX 0x7FFFFFFFFFFFFFFFLL
#define LLMIN 0X8000000000000000LL
typedef union
{
long long llnu;
double dbnu;
}ll_db_t;
typedef struct
{
long long base : 52;
int exp : 11;
int sign : 1;
}db_bits_t;
int abs_x(int x)
{
//return x >= 0 ? x : -x;
int y, z;
y = z = x;
z >>= 31;
y ^= z;
y -= z;
return y;
}
double fabs_x (double x)
{
//return x >= 0 ? x : -x;
long long y;
y = *(long long *)&x;
y &= LLMAX;
return *(double *)&y;
}
double ceil_x(double x)
{
double dmax = (double)(long long)LLMAX;
double dmin = (double)(long long)LLMIN;
if(x >= dmax || x<= dmin)
{
return x;
}
double y = (double)(long long)x;
x > y ? y += 1.0 : 0;
return y;
}
double floor_x(double x)
{
double dmax = (double)(long long)LLMAX;
double dmin = (double)(long long)LLMIN;
if(x >= dmax || x<= dmin)
return x;
double y = (double)(long long)x;
x < y ? y -= 1.0 : 0;
return y;
}
double frexp_x(double x, int *e)
{
double y = x;
short *s = (short *)&y + 3;
short w = *s;
*s &= 0xbfef;
*s |= 0x3fe0;
w &= 0x7fff;
w >>= 4;
w -= 0x03fe;
*e = w;
return y;
}
double ldexp_x(double x, int n)
{
db_bits_t *y = (db_bits_t *)&x;
y->exp += n;
return x;
/*
double y = x;
short s = *((unsigned short *)&y + 3);
short t = s & 0x000f;
s >>= 4;
s += n;
s <<= 4;
s |= t;
*((unsigned short *)&y + 3) = s;
return y;
*/
}
double fmod_x(double nu, double de)
{
de = fabs_x(de);
double fl = floor_x(nu / de);
return nu - fl * de;
}
double modf_x(double x, double *n)
{
ll_db_t y, intpart, fractpart;
y.dbnu = x;
long long flag = LLMIN & y.llnu;
y.llnu &= LLMAX;
intpart.dbnu = floor_x(y.dbnu);
fractpart.dbnu = y.dbnu - intpart.dbnu;
intpart.llnu |= flag;
fractpart.llnu |= flag;
*n = intpart.dbnu;
return fractpart.dbnu;
}