Skip to content

Commit

Permalink
Move checks to zlema() C code, fix 'n' calculation
Browse files Browse the repository at this point in the history
This uses many of the same checks, in the same order, as the ema() C
function. That makes it easier and safer to call zlema() from other C
functions.

This also fixes the issue flagged by clang-UBSAN: We approximated 'n'
using 'ratio', but it was possible that ratio = 0. There was a check
for ratio > 0 later in the function, but that didn't prevent the
possibility of division by 0.

Thanks to Prof Ripley for the report.

See #100, see #69.
  • Loading branch information
joshuaulrich committed Aug 30, 2020
1 parent f58a6a2 commit 771218a
Showing 1 changed file with 20 additions and 16 deletions.
36 changes: 20 additions & 16 deletions src/moving_averages.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,25 +286,29 @@ SEXP zlema (SEXP x, SEXP n, SEXP ratio) {
}
double *d_x = REAL(x);

/* If ratio is specified, and n is not, then
* set n to approx 'correct' value backed out from ratio
*/
int i_n;
double d_ratio;
if(R_NilValue == n && R_NilValue != ratio) {
d_ratio = asReal(ratio);
i_n = (int)(2.0 / d_ratio - 1.0);
} else {
i_n = asInteger(n);
if(ncols(x) > 1) {
error("ncol(x) > 1; ZLEMA only supports univariate 'x'");
}

/* Determine decay ratio */
if(R_NilValue == ratio) {
d_ratio = 2.0 / (i_n + 1);
int i_n = asInteger(n);
double d_ratio = asReal(ratio);

if(R_NilValue == n || i_n <= 0) {
if(R_NilValue == ratio || d_ratio <= 0.0) {
error("either 'n' or 'ratio' must be specified and > 0\n",
"'n' is ", n, " 'ratio' is ", ratio);
} else {
/* If ratio is specified, and n is not, set n to approx 'correct'
* value backed out from ratio */
i_n = (int)(2.0 / d_ratio - 1.0);
}
} else {
d_ratio = asReal(ratio);
if(d_ratio <= 0.0) {
error("'ratio' must be > 0");
/* Determine decay ratio */
if(R_NilValue == ratio) {
d_ratio = 2.0 / (i_n + 1);
} else {
/* ratio != NULL -> warn that 'n' will be used instead */
warning("both 'n' and 'ratio' are specified; using 'n'");
}
}

Expand Down

0 comments on commit 771218a

Please sign in to comment.