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 ade9bc84eb0f1..e4daaec203a42 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 18cf75087a776..847a2a441f50d 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 ce33f05997dca..8d55a589653b1 100644 --- a/VisualC/SDL/SDL.vcxproj.filters +++ b/VisualC/SDL/SDL.vcxproj.filters @@ -317,6 +317,7 @@ + diff --git a/configure b/configure index 7fd57c582b5b9..533d68d0c6812 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 2a9b464b0220f..53d74495d5d14 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 d1172d3adcc90..a8d230c46574e 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 ca6e811c08e72..422f47f7810fd 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 95b27389cad92..4c4da37ec6a5f 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 ada1ffedff7fb..7b0a6ca2df24e 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 2f7ee185c253d..29f583e101417 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 2ff4de4c5713d..be5a85c19aa7d 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 af1fcb306be24..61c334978b4ca 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 c266c9f357f1c..52a9ece161c4b 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 5d6573312b969..aac0e6014b788 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 7133837d5709c..fe86d5ec37ea2 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 0000000000000..a30ba54e64c8d --- /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 459ceeacc5ee1..eb7bdd597da0e 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 32e5cda7a006c..1c0c8a4e9730b 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 02d510c7e5191..b36d83c79567a 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) {