造轮子之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; }