From 394c310fa45093fc34f5e5be3fa4c61a92c2ae83 Mon Sep 17 00:00:00 2001 From: Richard Allen Date: Thu, 4 Oct 2012 15:36:55 +0000 Subject: [PATCH] IOQ3 commit 2291 --- reaction/code/game/bg_lib.c | 66 ++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/reaction/code/game/bg_lib.c b/reaction/code/game/bg_lib.c index 4be9f839..f0c05327 100644 --- a/reaction/code/game/bg_lib.c +++ b/reaction/code/game/bg_lib.c @@ -813,6 +813,43 @@ double atan2( double y, double x ) { #endif +/* +=============== +powN + +Raise a double to a integer power +=============== +*/ +static double powN( double base, int exp ) +{ + if( exp >= 0 ) + { + double result = 1.0; + + // calculate x, x^2, x^4, ... by repeated squaring + // and multiply together the ones corresponding to the + // binary digits of the exponent + // e.g. x^73 = x^(1 + 8 + 64) = x * x^8 * x^64 + while( exp > 0 ) + { + if( exp % 2 == 1 ) + result *= base; + + base *= base; + exp /= 2; + } + + return result; + } + // if exp is INT_MIN, the next clause will be upset, + // because -exp isn't representable + else if( exp == INT_MIN ) + return powN( base, exp + 1 ) / base; + // x < 0 + else + return 1.0 / powN( base, -exp ); +} + double tan( double x ) { return sin(x) / cos(x); } @@ -1087,7 +1124,7 @@ double strtod( const char *nptr, char **endptr ) if( end != s && tolower( *nptr ) == 'p' ) { int exp; - float res2; + //float res2; // apparently (confusingly) the exponent should be // decimal exp = strtol( &nptr[1], (char **)&end, 10 ); @@ -1098,7 +1135,10 @@ double strtod( const char *nptr, char **endptr ) *endptr = (char *)nptr; return res; } - if( exp > 0 ) + + res *= powN( 2, exp ); + +/* if( exp > 0 ) { while( exp-- > 0 ) { @@ -1119,7 +1159,8 @@ double strtod( const char *nptr, char **endptr ) break; res = res2; } - } + } */ + } if( endptr ) *endptr = (char *)end; @@ -1153,7 +1194,7 @@ double strtod( const char *nptr, char **endptr ) if( p != end && tolower( *nptr ) == 'e' ) { int exp; - float res10; + //float res10; exp = strtol( &nptr[1], (char **)&end, 10 ); if( &nptr[1] == end ) { @@ -1162,7 +1203,10 @@ double strtod( const char *nptr, char **endptr ) *endptr = (char *)nptr; return res; } - if( exp > 0 ) + + res *= powN( 10, exp ); + +/* if( exp > 0 ) { while( exp-- > 0 ) { @@ -1185,7 +1229,7 @@ double strtod( const char *nptr, char **endptr ) break; res = res10; } - } + } */ } if( endptr ) *endptr = (char *)end; @@ -1960,7 +2004,7 @@ static LDOUBLE abs_val (LDOUBLE value) return result; } -static LDOUBLE pow10 (int exp) +/* static LDOUBLE pow10 (int exp) { LDOUBLE result = 1; @@ -1971,7 +2015,7 @@ static LDOUBLE pow10 (int exp) } return result; -} +} */ static long round (LDOUBLE value) { @@ -2035,12 +2079,12 @@ static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, /* We "cheat" by converting the fractional part to integer by * multiplying by a factor of 10 */ - fracpart = round ((pow10 (max)) * (ufvalue - intpart)); + fracpart = round ((powN (10, max)) * (ufvalue - intpart)); - if (fracpart >= pow10 (max)) + if (fracpart >= powN (10, max)) { intpart++; - fracpart -= pow10 (max); + fracpart -= powN (10, max); } #ifdef DEBUG_SNPRINTF