From 19c6635ff05095d2e7fb522a9e482997c8154bb4 Mon Sep 17 00:00:00 2001 From: Marius Gerbershagen Date: Tue, 12 Feb 2019 22:37:23 +0100 Subject: [PATCH] expt: use pow function for floating point numbers Improves speed and accurracy. --- src/aclocal.m4 | 2 +- src/c/numbers/expt.d | 9 +++++++++ src/cmp/sysfun.lsp | 3 +++ src/configure | 18 +++++++++++++++--- src/configure.ac | 2 +- src/ecl/configpre.h | 6 ++++++ src/h/internal.h | 6 ++++++ 7 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/aclocal.m4 b/src/aclocal.m4 index d4f7fdfab..c1cb58126 100644 --- a/src/aclocal.m4 +++ b/src/aclocal.m4 @@ -6,7 +6,7 @@ AC_DEFUN([ECL_LONG_DOUBLE],[ if test "$enable_longdouble" != "no" ; then AC_CHECK_TYPES([long double],[enable_longdouble=yes],[enable_longdouble=no]) if test "$enable_longdouble" != "no" ; then -AC_CHECK_FUNCS([sinl cosl tanl logl expl ldexpl frexpl],[],[enable_longdouble=no; break]) +AC_CHECK_FUNCS([sinl cosl tanl logl expl powl ldexpl frexpl],[],[enable_longdouble=no; break]) if test "$enable_longdouble" != "no" ; then AC_DEFINE([ECL_LONG_FLOAT], [], [ECL_LONG_FLOAT]) fi diff --git a/src/c/numbers/expt.d b/src/c/numbers/expt.d index d864cb550..b1ad691c0 100644 --- a/src/c/numbers/expt.d +++ b/src/c/numbers/expt.d @@ -102,6 +102,15 @@ ecl_expt(cl_object x, cl_object y) z = x; if (!ecl_plusp(ty==t_complex?y->complex.real:y)) z = ecl_divide(ecl_make_fixnum(1), z); + } else if (tx == t_singlefloat && ty == t_singlefloat + && ecl_single_float(x) >= 0.0f) { + z = ecl_make_single_float(powf(ecl_single_float(x), ecl_single_float(y))); + } else if (tx == t_doublefloat && ty == t_doublefloat + && ecl_double_float(x) >= 0.0) { + z = ecl_make_double_float(pow(ecl_double_float(x), ecl_double_float(y))); + } else if (tx == t_longfloat && ty == t_longfloat + && ecl_long_float(x) >= 0.0l) { + z = ecl_make_long_float(powl(ecl_long_float(x), ecl_long_float(y))); } else if (ty != t_fixnum && ty != t_bignum) { /* The following could be just z = ecl_log1(x); diff --git a/src/cmp/sysfun.lsp b/src/cmp/sysfun.lsp index 8d2fb15d9..d65dd74fd 100644 --- a/src/cmp/sysfun.lsp +++ b/src/cmp/sysfun.lsp @@ -507,6 +507,9 @@ (def-inline expt :always ((integer 2 2) (integer 0 29)) :fixnum "(1<<(#1))") (def-inline expt :always ((integer 0 0) t) :fixnum "0") (def-inline expt :always ((integer 1 1) t) :fixnum "1") +(def-inline expt :always ((long-float 0.0 *) long-float) :long-double "powl((long double)#0,(long double)#1)") +(def-inline expt :always ((double-float 0.0 *) double-float) :double "pow((double)#0,(double)#1)") +(def-inline expt :always ((single-float 0.0 *) single-float) :float "powf((float)#0,(float)#1)") #+long-float (def-inline log :always (fixnum-float) :long-double "logl((long double)(#0))" :exact-return-type t) diff --git a/src/configure b/src/configure index bfbcdbdf1..015aa0484 100755 --- a/src/configure +++ b/src/configure @@ -737,6 +737,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -863,6 +864,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1115,6 +1117,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1252,7 +1263,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1405,6 +1416,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -8157,7 +8169,7 @@ else fi if test "$enable_longdouble" != "no" ; then -for ac_func in sinl cosl tanl logl expl ldexpl frexpl +for ac_func in sinl cosl tanl logl expl powl ldexpl frexpl 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" @@ -9377,7 +9389,7 @@ $as_echo "$as_me: WARNING: feenableexcept not declared: disabling floating point fi -for ac_func in expf logf sqrtf cosf sinf tanf sinhf coshf tanhf \ +for ac_func in expf powf logf sqrtf cosf sinf tanf sinhf coshf tanhf \ floorf ceilf fabsf frexpf ldexpf log1p log1pf log1pl \ copysign do : diff --git a/src/configure.ac b/src/configure.ac index 1429e7511..1656defb0 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -725,7 +725,7 @@ AC_CHECK_DECL([feenableexcept], [AC_MSG_WARN(feenableexcept not declared: disabling floating point exceptions)], [#include ]) -AC_CHECK_FUNCS( [expf logf sqrtf cosf sinf tanf sinhf coshf tanhf] \ +AC_CHECK_FUNCS( [expf powf logf sqrtf cosf sinf tanf sinhf coshf tanhf] \ [floorf ceilf fabsf frexpf ldexpf log1p log1pf log1pl] \ [copysign] ) diff --git a/src/ecl/configpre.h b/src/ecl/configpre.h index c672170fa..908847925 100644 --- a/src/ecl/configpre.h +++ b/src/ecl/configpre.h @@ -268,6 +268,12 @@ /* HAVE_POSIX_RWLOCK */ #undef HAVE_POSIX_RWLOCK +/* Define to 1 if you have the `powf' function. */ +#undef HAVE_POWF + +/* Define to 1 if you have the `powl' function. */ +#undef HAVE_POWL + /* Define to 1 if the system has the type `pthread_rwlock_t'. */ #undef HAVE_PTHREAD_RWLOCK_T diff --git a/src/h/internal.h b/src/h/internal.h index e3a8ca9ec..d7cc1bd00 100755 --- a/src/h/internal.h +++ b/src/h/internal.h @@ -566,6 +566,12 @@ extern void ecl_interrupt_process(cl_object process, cl_object function); # endif # define expf(x) exp((float)x) #endif +#ifndef HAVE_POWF +# ifdef powf +# undef powf +# endif +# define powf(x,y) pow((float)x,(float)y) +#endif #ifndef HAVE_LOGF # ifdef logf # undef logf