diff --git a/src/c/numbers/log.d b/src/c/numbers/log.d index dd1e0ec95..68e939a3b 100644 --- a/src/c/numbers/log.d +++ b/src/c/numbers/log.d @@ -17,6 +17,7 @@ #include #include #include +#include #include #pragma STDC FENV_ACCESS ON @@ -88,6 +89,22 @@ ecl_log1_simple(cl_object x) return ecl_make_single_float(logf(ecl_to_float(x))); } +static cl_object +ecl_log1_ratio(cl_object x) +{ + cl_object num = x->ratio.num; + cl_object den = x->ratio.den; + cl_index lnum = ecl_integer_length(num); + cl_index lden = ecl_integer_length(den); + if ((lnum > lden) ? (lnum - lden >= FLT_MAX_EXP) : (lden - lnum >= -FLT_MIN_EXP)) { + cl_object numlog = ecl_log1(num); + cl_object denlog = ecl_log1(den); + return ecl_minus(numlog, denlog); + } else { + return ecl_log1_simple(x); + } +} + static cl_object ecl_log1_single_float(cl_object x) { @@ -182,7 +199,7 @@ ecl_log1_clfloat(cl_object x) #endif MATH_DEF_DISPATCH1(log1, @[log], @[number], - ecl_log1_simple, ecl_log1_bignum, ecl_log1_simple, + ecl_log1_simple, ecl_log1_bignum, ecl_log1_ratio, ecl_log1_single_float, ecl_log1_double_float, ecl_log1_long_float, ecl_log1_complex, ecl_log1_csfloat, ecl_log1_cdfloat, ecl_log1_clfloat); diff --git a/src/h/impl/math_dispatch.h b/src/h/impl/math_dispatch.h index 6acf3cffe..23f900206 100644 --- a/src/h/impl/math_dispatch.h +++ b/src/h/impl/math_dispatch.h @@ -54,6 +54,7 @@ typedef cl_object (*math_one_arg_fn)(cl_object); } \ return name##dispatch[t](arg); \ } + #define MATH_DEF_DISPATCH1(name,id,type,fix,big,ratio, \ single_float,double_float,long_float, \ complex,csfloat,cdfloat,clfloat) \ diff --git a/src/tests/normal-tests/mixed.lsp b/src/tests/normal-tests/mixed.lsp index 0d7522e39..c3f82c51b 100644 --- a/src/tests/normal-tests/mixed.lsp +++ b/src/tests/normal-tests/mixed.lsp @@ -429,3 +429,8 @@ (let ((vector (si:make-vector t 10 t nil nil nil))) (si:adjust-vector vector 20) (is (= 20 (array-total-size vector))))) + +;;; Created: 2022-11-10 +;;; Contains: a test for a logarithm of a very small ratio +(test mix.0023.log-small-ratio + (finishes (log (/ 1 6319748715279270675921934218987893281199411530039296))))