Hi, ... was offline, sorry.
On Saturday 17 June 2006 23:28, Erik Hofman wrote: > You know, I did a quick grep in the source code for fast_ and only found > it to be used in simgear/sound/xmlsound.cxx (namely fast_log10 and > fast_log). Maybe we can get rid of them after all. In that time, I have tried to fix fastmath.cpp to compile correctly. My suggestion would be to keep the transcendent functions and correct them to make them compile correct. I have also removed the functions that are very most likely slower than the libm implementations from the header. Can you/somebody help me please and double check the attached patch if I have converted them correctly before I check that in? I have *not* done any tests with this functions against the libm ones. In fact I do not know what error is acceptable for the fast implementation. What do you think? Greetings Mathias -- Mathias Fröhlich, email: [EMAIL PROTECTED]
Index: simgear/math/fastmath.cxx =================================================================== RCS file: /var/cvs/SimGear-0.3/SimGear/simgear/math/fastmath.cxx,v retrieving revision 1.8 diff -u -r1.8 fastmath.cxx --- simgear/math/fastmath.cxx 16 Jun 2006 09:29:54 -0000 1.8 +++ simgear/math/fastmath.cxx 19 Jun 2006 17:03:05 -0000 @@ -35,20 +35,20 @@ * This function is on avarage 9 times faster than the system exp() function * and has an error of about 1.5% */ -static union { - double d; - struct { +double fast_exp(double val) { + const double a = 1048576/M_LN2; + const double b_c = 1072632447; /* 1072693248 - 60801 */ + + union { + double d; + struct { #if BYTE_ORDER == BIG_ENDIAN int i, j; #else int j, i; #endif - } n; -} _eco; - -double fast_exp(double val) { - const double a = 1048576/M_LN2; - const double b_c = 1072632447; /* 1072693248 - 60801 */ + } n; + } _eco; _eco.n.i = (int)(a*val + b_c); @@ -61,30 +61,30 @@ */ double fast_exp2( const double val ) { - int e; - double ret; - - if (val >= 0) { - e = int (val); - ret = val - (e - 1); - + union { + double d; + struct { #if BYTE_ORDER == BIG_ENDIAN - ((*((int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20; + int i, j; #else - ((*(1 + (int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20; + int j, i; #endif + } n; + } ret; + + if (val >= 0) { + int e = int (val); + ret.d = val - (e - 1); + ret.n.i &= ~(2047 << 20); + ret.n.i += (e + 1023) << 20; } else { - e = int (val + 1023); - ret = val - (e - 1024); - -#if BYTE_ORDER == BIG_ENDIAN - ((*((int *) &ret)) &= ~(2047 << 20)) += e << 20; -#else - ((*(1 + (int *) &ret)) &= ~(2047 << 20)) += e << 20; -#endif + int e = int (val + 1023); + ret.d = val - (e - 1024); + ret.n.i &= ~(2047 << 20); + ret.n.i += e << 20; } - return ret; + return ret.d; } @@ -96,7 +96,12 @@ float result, tmp; float mp = 0.346607f; - result = *(int*)&val; + union { + float f; + int i; + } v; + v.f = val; + result = v.i; result *= 1.0/(1<<23); result = result - 127; @@ -115,27 +120,14 @@ result = val + 127 - tmp; result *= (1<<23); - *(int*)&result = (int)result; - return result; -} - - - -/** - * While we're on the subject, someone might have use for these as well? - * Float Shift Left and Float Shift Right. Do what you want with this. - */ -void fast_BSL(float &x, register unsigned long shiftAmount) { - - *(unsigned long*)&x+=shiftAmount<<23; - + union { + float f; + int i; + } v; + v.i = (int)result; + return v.f; } -void fast_BSR(float &x, register unsigned long shiftAmount) { - - *(unsigned long*)&x-=shiftAmount<<23; - -} /* @@ -148,20 +140,28 @@ */ float fast_pow(const float f, const int n) { - long *lp,l; - lp=(long*)(&f); - l=*lp;l-=0x3F800000l;l<<=(n-1);l+=0x3F800000l; - *lp=l; - return f; + union { + float f; + int i; + } v; + v.f = f; + v.i -= 0x3F800000l; + v.i <<= (n-1); + v.i += 0x3F800000l; + return v.f; } float fast_root(const float f, const int n) { - long *lp,l; - lp=(long*)(&f); - l=*lp;l-=0x3F800000l;l>>=(n-1);l+=0x3F800000l; - *lp=l; - return f; + union { + float f; + int i; + } v; + v.f = f; + v.i -= 0x3F800000l; + v.i >>= (n-1); + v.i += 0x3F800000l; + return v.f; } Index: simgear/math/fastmath.hxx =================================================================== RCS file: /var/cvs/SimGear-0.3/SimGear/simgear/math/fastmath.hxx,v retrieving revision 1.9 diff -u -r1.9 fastmath.hxx --- simgear/math/fastmath.hxx 17 Jun 2006 16:04:28 -0000 1.9 +++ simgear/math/fastmath.hxx 19 Jun 2006 17:03:05 -0000 @@ -45,10 +45,6 @@ float fast_acos(const float val); float fast_atan(const float val); -void fast_BSL(float &x, register unsigned long shiftAmount); -void fast_BSR(float &x, register unsigned long shiftAmount); - - inline float fast_log2 (float val) { union { @@ -89,74 +85,10 @@ return _fast_pow2(val2 * _fast_log2(val1)); } - -/* - * Haven't seen this elsewhere, probably because it is too obvious? - * Anyway, these functions are intended for 32-bit floating point numbers - * only and should work a bit faster than the regular ones. - */ -inline float fast_abs(float f) +inline float float_to_int(float F) { - union { - float f; - int i; - } v; - v.f = f; - v.i = v.i&0x7fffffff; - return v.f; + return (int) ((F) < 0.0f ? (F)-0.5f : (F)+0.5f); } -inline float fast_neg(float f) -{ - union { - float f; - int i; - } v; - v.f = f; - v.i = v.i^0x80000000; - return v.f; -} - -inline int fast_sgn(float f) -{ - union { - float f; - int i; - } v; - v.f = f; - return 1+((v.i>>31)<<1); -} - - - -/** - * Quick rounding function. - */ -#if defined(i386) -#define USE_X86_ASM -#endif - -#if defined(USE_X86_ASM) -static __inline__ int float_to_int(float f) -{ - int r; - __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); - return r; -} -#elif defined(__MSC__) && defined(__WIN32__) -static __inline int float_to_int(float f) -{ - int r; - _asm { - fld f - fistp r - } - return r; -} -#else -#define float_to_int(F) ((int) ((F) < 0.0f ? (F)-0.5f : (F)+0.5f)) -#endif - - #endif // !_SG_FMATH_HXX
_______________________________________________ Flightgear-devel mailing list Flightgear-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/flightgear-devel