From 11c348b4d7a27f74e3cd7a745bc3fc8b60345aef Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Wed, 17 Jan 2018 11:53:09 -0500 Subject: [PATCH] SDL_log10 --- CMakeLists.txt | 2 +- VisualC/SDL/SDL.vcxproj | 1 + VisualC/SDL/SDL.vcxproj.filters | 1 + configure | 2 +- configure.in | 2 +- include/SDL_config.h.cmake | 2 + include/SDL_config.h.in | 2 + include/SDL_config_android.h | 2 + include/SDL_config_iphoneos.h | 2 + include/SDL_config_macosx.h | 2 + include/SDL_config_pandora.h | 1 + include/SDL_config_psp.h | 2 + include/SDL_config_windows.h | 2 + include/SDL_config_winrt.h | 2 + include/SDL_config_wiz.h | 2 + src/libm/e_log10.c | 106 ++++++++++++++++++++++++++++++++ src/libm/math_libm.h | 1 + src/libm/math_private.h | 1 + src/stdlib/SDL_stdlib.c | 20 ++++++ 19 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 src/libm/e_log10.c diff --git a/CMakeLists.txt b/CMakeLists.txt index ade9bc84e..e4daaec20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -643,7 +643,7 @@ if(LIBC) _stricmp _strnicmp sscanf acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf fabs fabsf floor floorf fmod fmodf - log logf pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf) + log logf log10 log10f pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf) string(TOUPPER ${_FN} _UPPER) set(HAVE_${_UPPER} 1) endforeach() diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj index 18cf75087..847a2a441 100644 --- a/VisualC/SDL/SDL.vcxproj +++ b/VisualC/SDL/SDL.vcxproj @@ -420,6 +420,7 @@ + diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters index ce33f0599..8d55a5896 100644 --- a/VisualC/SDL/SDL.vcxproj.filters +++ b/VisualC/SDL/SDL.vcxproj.filters @@ -317,6 +317,7 @@ + diff --git a/configure b/configure index 7fd57c582..533d68d0c 100755 --- a/configure +++ b/configure @@ -16690,7 +16690,7 @@ if test "x$ac_cv_lib_m_pow" = xyes; then : LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm" fi - for ac_func in acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf fabs fabsf floor floorf fmod fmodf log logf pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf + for ac_func in acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf fabs fabsf floor floorf fmod fmodf log logf log10 log10f pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.in b/configure.in index 2a9b464b0..53d74495d 100644 --- a/configure.in +++ b/configure.in @@ -271,7 +271,7 @@ if test x$enable_libc = xyes; then AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll) AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"]) - AC_CHECK_FUNCS(acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf fabs fabsf floor floorf fmod fmodf log logf pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf) + AC_CHECK_FUNCS(acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf fabs fabsf floor floorf fmod fmodf log logf log10 log10f pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf) AC_CHECK_LIB(iconv, iconv_open, [LIBS="$LIBS -liconv"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -liconv"]) AC_CHECK_FUNCS(iconv) diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index d1172d3ad..a8d230c46 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -152,6 +152,8 @@ #cmakedefine HAVE_FMODF 1 #cmakedefine HAVE_LOG 1 #cmakedefine HAVE_LOGF 1 +#cmakedefine HAVE_LOG10 1 +#cmakedefine HAVE_LOG10F 1 #cmakedefine HAVE_POW 1 #cmakedefine HAVE_POWF 1 #cmakedefine HAVE_SCALBN 1 diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index ca6e811c0..422f47f78 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -157,6 +157,8 @@ #undef HAVE_FMODF #undef HAVE_LOG #undef HAVE_LOGF +#undef HAVE_LOG10 +#undef HAVE_LOG10F #undef HAVE_POW #undef HAVE_POWF #undef HAVE_SCALBN diff --git a/include/SDL_config_android.h b/include/SDL_config_android.h index 95b27389c..4c4da37ec 100644 --- a/include/SDL_config_android.h +++ b/include/SDL_config_android.h @@ -106,6 +106,8 @@ #define HAVE_FMODF 1 #define HAVE_LOG 1 #define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 #define HAVE_POW 1 #define HAVE_POWF 1 #define HAVE_SCALBN 1 diff --git a/include/SDL_config_iphoneos.h b/include/SDL_config_iphoneos.h index ada1ffedf..7b0a6ca2d 100644 --- a/include/SDL_config_iphoneos.h +++ b/include/SDL_config_iphoneos.h @@ -107,6 +107,8 @@ #define HAVE_FMODF 1 #define HAVE_LOG 1 #define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 #define HAVE_POW 1 #define HAVE_POWF 1 #define HAVE_SCALBN 1 diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index 2f7ee185c..29f583e10 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -110,6 +110,8 @@ #define HAVE_FMODF 1 #define HAVE_LOG 1 #define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 #define HAVE_POW 1 #define HAVE_POWF 1 #define HAVE_SCALBN 1 diff --git a/include/SDL_config_pandora.h b/include/SDL_config_pandora.h index 2ff4de4c5..be5a85c19 100644 --- a/include/SDL_config_pandora.h +++ b/include/SDL_config_pandora.h @@ -93,6 +93,7 @@ #define HAVE_FABS 1 #define HAVE_FLOOR 1 #define HAVE_LOG 1 +#define HAVE_LOG10 1 #define HAVE_SCALBN 1 #define HAVE_SIN 1 #define HAVE_SINF 1 diff --git a/include/SDL_config_psp.h b/include/SDL_config_psp.h index af1fcb306..61c334978 100644 --- a/include/SDL_config_psp.h +++ b/include/SDL_config_psp.h @@ -105,6 +105,8 @@ #define HAVE_FMODF 1 #define HAVE_LOG 1 #define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 #define HAVE_POW 1 #define HAVE_POWF 1 #define HAVE_SCALBN 1 diff --git a/include/SDL_config_windows.h b/include/SDL_config_windows.h index c266c9f35..52a9ece16 100644 --- a/include/SDL_config_windows.h +++ b/include/SDL_config_windows.h @@ -147,6 +147,8 @@ typedef unsigned int uintptr_t; #define HAVE_FMODF 1 #define HAVE_LOG 1 #define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 #define HAVE_POW 1 #define HAVE_POWF 1 #define HAVE_SIN 1 diff --git a/include/SDL_config_winrt.h b/include/SDL_config_winrt.h index 5d6573312..aac0e6014 100644 --- a/include/SDL_config_winrt.h +++ b/include/SDL_config_winrt.h @@ -163,6 +163,8 @@ typedef unsigned int uintptr_t; #define HAVE_FMODF 1 #define HAVE_LOG 1 #define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 #define HAVE_POW 1 #define HAVE_POWF 1 #define HAVE__SCALB 1 diff --git a/include/SDL_config_wiz.h b/include/SDL_config_wiz.h index 7133837d5..fe86d5ec3 100644 --- a/include/SDL_config_wiz.h +++ b/include/SDL_config_wiz.h @@ -102,6 +102,8 @@ #define HAVE_FMODF 1 #define HAVE_LOG 1 #define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 #define HAVE_POW 1 #define HAVE_POWF 1 #define HAVE_SCALBN 1 diff --git a/src/libm/e_log10.c b/src/libm/e_log10.c new file mode 100644 index 000000000..a30ba54e6 --- /dev/null +++ b/src/libm/e_log10.c @@ -0,0 +1,106 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */ +/* C4723: potential divide by zero. */ +#pragma warning ( disable : 4723 ) +#endif + +/* __ieee754_log10(x) + * Return the base 10 logarithm of x + * + * Method : + * Let log10_2hi = leading 40 bits of log10(2) and + * log10_2lo = log10(2) - log10_2hi, + * ivln10 = 1/log(10) rounded. + * Then + * n = ilogb(x), + * if(n<0) n = n+1; + * x = scalbn(x,-n); + * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x)) + * + * Note 1: + * To guarantee log10(10**n)=n, where 10**n is normal, the rounding + * mode must set to Round-to-Nearest. + * Note 2: + * [1/log(10)] rounded to 53 bits has error .198 ulps; + * log10 is monotonic at all binary break points. + * + * Special cases: + * log10(x) is NaN with signal if x < 0; + * log10(+INF) is +INF with no signal; log10(0) is -INF with signal; + * log10(NaN) is that NaN with no signal; + * log10(10**N) = N for N=0,1,...,22. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "math_libm.h" +#include "math_private.h" + +static const double +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */ +log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ +log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ + +static const double zero = 0.0; + +double attribute_hidden __ieee754_log10(double x) +{ + double y,z; + int32_t i,k,hx; + u_int32_t lx; + + EXTRACT_WORDS(hx,lx,x); + + k=0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx&0x7fffffff)|lx)==0) + return -two54/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 54; x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx,x); + } + if (hx >= 0x7ff00000) return x+x; + k += (hx>>20)-1023; + i = ((u_int32_t)k&0x80000000)>>31; + hx = (hx&0x000fffff)|((0x3ff-i)<<20); + y = (double)(k+i); + SET_HIGH_WORD(x,hx); + z = y*log10_2lo + ivln10*__ieee754_log(x); + return z+y*log10_2hi; +} + +/* + * wrapper log10(X) + */ +#ifndef _IEEE_LIBM +double log10(double x) +{ + double z = __ieee754_log10(x); + if (_LIB_VERSION == _IEEE_ || isnan(x)) + return z; + if (x <= 0.0) { + if(x == 0.0) + return __kernel_standard(x, x, 18); /* log10(0) */ + return __kernel_standard(x, x, 19); /* log10(x<0) */ + } + return z; +} +#else +strong_alias(__ieee754_log10, log10) +#endif +libm_hidden_def(log10) diff --git a/src/libm/math_libm.h b/src/libm/math_libm.h index 459ceeacc..eb7bdd597 100644 --- a/src/libm/math_libm.h +++ b/src/libm/math_libm.h @@ -30,6 +30,7 @@ double SDL_uclibc_fabs(double x); double SDL_uclibc_floor(double x); double SDL_uclibc_fmod(double x, double y); double SDL_uclibc_log(double x); +double SDL_uclibc_log10(double x); double SDL_uclibc_pow(double x, double y); double SDL_uclibc_scalbn(double x, int n); double SDL_uclibc_sin(double x); diff --git a/src/libm/math_private.h b/src/libm/math_private.h index 32e5cda7a..1c0c8a4e9 100644 --- a/src/libm/math_private.h +++ b/src/libm/math_private.h @@ -39,6 +39,7 @@ typedef unsigned int u_int32_t; #define floor SDL_uclibc_floor #define __ieee754_fmod SDL_uclibc_fmod #define __ieee754_log SDL_uclibc_log +#define __ieee754_log10 SDL_uclibc_log10 #define __ieee754_pow SDL_uclibc_pow #define scalbln SDL_uclibc_scalbln #define scalbn SDL_uclibc_scalbn diff --git a/src/stdlib/SDL_stdlib.c b/src/stdlib/SDL_stdlib.c index 02d510c7e..b36d83c79 100644 --- a/src/stdlib/SDL_stdlib.c +++ b/src/stdlib/SDL_stdlib.c @@ -280,6 +280,26 @@ SDL_logf(float x) #endif } +double +SDL_log10(double x) +{ +#if defined(HAVE_LOG10) + return log10(x); +#else + return SDL_uclibc_log10(x); +#endif +} + +float +SDL_log10f(float x) +{ +#if defined(HAVE_LOG10F) + return log10f(x); +#else + return (float)SDL_log10((double)x); +#endif +} + double SDL_pow(double x, double y) {