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
[email protected]
https://lists.sourceforge.net/lists/listinfo/flightgear-devel