/* * "rustic" math library, for muLinux * (C) by M. Andreoli & E. Cavalli * This library emulate the math library. Linking the math.o, avoid the use of -lm in compiling. This orrendous piece of code use Taylor series expansions and other dirty hack. USE AT OWN RISK! */ #define PI 3.14159265359 #define LN_10 2.30258509 /* ln(10) */ #define SQRT_E 1.6487212707 #define double double #define ABS(x) ( (x)>=0?(x):(-x) ) /* exp() */ double exp2( double x) { double x2,x212; if(x<0.5) { x2=x*x; x212=12.0+x2; return (x212+6.0*x)/(x212-6.0*x); } else { x-=0.5; x2=x*x; x212=12.0+x2; return SQRT_E*(x212+6.0*x)/(x212-6.0*x); } } double exp(double x) { double r,rest; int i,m,sign; sign= (int)(x>=0?1.0:-1.0); x=sign*x; m=(int)x; rest=x-1.0*(int)x; r=1.0; for (i=0; i0? r*exp2(rest) : exp2(-rest)/r; } /* cos(x) */ double cos(double x) { double y,x2,x4; int n; x=ABS(x); n=(int) (x/(2.0*PI)); y=x - n*PI*2.0-PI; x2=y*y; x4=x2*x2; return -(1. - 0.4563492063492063*x2 + 0.0207010582010582*x4)/ (1. + 0.04365079365079364*x2 + 0.00085978835978836*x4); } /* sin(x) */ double sin(double x) { return cos(PI/2.0-x); } /* ceil(x) */ double ceil(double x) { int i; i=(int) x; return i; } /* log(x) if x is near x */ double log_serie(double y) { double x,p,sum; int i,sign, iter=80; if ( (y-1.0 < 0.00001) && ( y-1.0 > -0.00001 ) ) return 0.0; if ( y > 1.0 ) { x=y-1; sum=x; sign=-1; p=x*x; for(i=2; i<=iter; i++) { sum=sum +sign*p/i; p*=x; sign*=-1; } } else { x=1-y; sum=x; p=x*x; for(i=2; i<=iter; i++) { sum=sum +p/i; p*=x; } sum*=-1; } return sum; } /* log(x) : a dirty hack! */ double log( double x) { char buf[64]; float man, ex; sprintf(buf,"%2.2E",x); buf[4]='\0'; buf[8]='\0'; man=atof(buf); ex=atof(buf+5); /* reduce mantissa < 1 */ man/=10.0; ex++; return log_serie(man) + ex*LN_10; } /* sqrt(x) */ double sqrt(double x) { if ( x < 0.0 ) { printf("sqrt: x < 0\n"); exit(1);} return (double) exp(0.5*log(x)); } /* pow(x,y) */ double pow (double b, double x) { if ( b < 0.0 ) { printf("pow: base < 0\n"); exit(1);} return (double) exp(x*log(b)); }