From 99579c72dc08bb40aaa588d38636096a5e435302 Mon Sep 17 00:00:00 2001 From: badasahog <52379863+badasahog@users.noreply.github.com> Date: Thu, 7 Aug 2025 07:58:33 -0400 Subject: [PATCH] replace R_FINITE with c99's isfinite --- src/assign.c | 10 +++++----- src/data.table.h | 1 + src/fastmean.c | 6 +++--- src/forder.c | 10 +++++----- src/freadR.c | 2 +- src/froll.c | 28 ++++++++++++++-------------- src/frolladaptive.c | 12 ++++++------ src/utils.c | 4 ++-- 8 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/assign.c b/src/assign.c index eee00cc0f5..04cf0324c1 100644 --- a/src/assign.c +++ b/src/assign.c @@ -967,14 +967,14 @@ const char *memrecycle(const SEXP target, const SEXP where, const int start, con case INTSXP: CHECK_RANGE(int, INTEGER, val<0 || val>255, val, _("%d (type '%s') at RHS position %d taken as 0 when assigning to type '%s' %s")) case REALSXP: if (sourceIsI64) CHECK_RANGE(int64_t, REAL, val<0 || val>255, val, _("%"PRId64" (type '%s') at RHS position %d taken as 0 when assigning to type '%s' %s")) - else CHECK_RANGE(double, REAL, !R_FINITE(val) || val<0.0 || val>256.0 || (int)val!=val, val, _("%f (type '%s') at RHS position %d either truncated (precision lost) or taken as 0 when assigning to type '%s' %s")) + else CHECK_RANGE(double, REAL, !isfinite(val) || val<0.0 || val>256.0 || (int)val!=val, val, _("%f (type '%s') at RHS position %d either truncated (precision lost) or taken as 0 when assigning to type '%s' %s")) } break; case INTSXP: switch (TYPEOF(source)) { case REALSXP: if (sourceIsI64) CHECK_RANGE(int64_t, REAL, val!=NA_INTEGER64 && (val<=NA_INTEGER || val>INT_MAX), val, _("%"PRId64" (type '%s') at RHS position %d out-of-range (NA) when assigning to type '%s' %s")) else CHECK_RANGE(double, REAL, !ISNAN(val) && (!within_int32_repres(val) || (int)val!=val), val, _("%f (type '%s') at RHS position %d out-of-range(NA) or truncated (precision lost) when assigning to type '%s' %s")) - case CPLXSXP: CHECK_RANGE(Rcomplex, COMPLEX, !((ISNAN(val.i) || (R_FINITE(val.i) && val.i==0.0)) && + case CPLXSXP: CHECK_RANGE(Rcomplex, COMPLEX, !((ISNAN(val.i) || (isfinite(val.i) && val.i==0.0)) && (ISNAN(val.r) || (within_int32_repres(val.r) && (int)val.r==val.r))), val.r, _("%f (type '%s') at RHS position %d either imaginary part discarded or real part truncated (precision lost) when assigning to type '%s' %s")) } break; case REALSXP: @@ -983,9 +983,9 @@ const char *memrecycle(const SEXP target, const SEXP where, const int start, con CHECK_RANGE(double, REAL, !ISNAN(val) && (!within_int64_repres(val) || (int64_t)val!=val), val, _("%f (type '%s') at RHS position %d out-of-range(NA) or truncated (precision lost) when assigning to type '%s' %s")) break; case CPLXSXP: if (targetIsI64) - CHECK_RANGE(Rcomplex, COMPLEX, !((ISNAN(val.i) || (R_FINITE(val.i) && val.i==0.0)) && - (ISNAN(val.r) || (R_FINITE(val.r) && (int64_t)val.r==val.r))), val.r, _("%f (type '%s') at RHS position %d either imaginary part discarded or real part truncated (precision lost) when assigning to type '%s' %s")) - else CHECK_RANGE(Rcomplex, COMPLEX, !(ISNAN(val.i) || (R_FINITE(val.i) && val.i==0.0)), val.r, _("%f (type '%s') at RHS position %d imaginary part discarded when assigning to type '%s' %s")) + CHECK_RANGE(Rcomplex, COMPLEX, !((ISNAN(val.i) || (isfinite(val.i) && val.i==0.0)) && + (ISNAN(val.r) || (isfinite(val.r) && (int64_t)val.r==val.r))), val.r, _("%f (type '%s') at RHS position %d either imaginary part discarded or real part truncated (precision lost) when assigning to type '%s' %s")) + else CHECK_RANGE(Rcomplex, COMPLEX, !(ISNAN(val.i) || (isfinite(val.i) && val.i==0.0)), val.r, _("%f (type '%s') at RHS position %d imaginary part discarded when assigning to type '%s' %s")) } } } diff --git a/src/data.table.h b/src/data.table.h index a734863f54..5dfae59992 100644 --- a/src/data.table.h +++ b/src/data.table.h @@ -21,6 +21,7 @@ #include // for uint64_t rather than unsigned long long #include // for va_list, va_start #include +#include // isfinite #include "types.h" #include "po.h" #ifdef WIN32 // positional specifiers (%n$) used in translations; #4402 diff --git a/src/fastmean.c b/src/fastmean.c index fa77fc97ce..e54c567f1f 100644 --- a/src/fastmean.c +++ b/src/fastmean.c @@ -70,7 +70,7 @@ SEXP fastmean(SEXP args) break; } s /= n; - if(R_FINITE((double)s)) { + if(isfinite((double)s)) { for (int i=0; imax) max=tmp; else if (tmp= 0.0) + if (isfinite(REAL(nrowLimitArg)[0]) && REAL(nrowLimitArg)[0] >= 0.0) args.nrowLimit = (int64_t)(REAL(nrowLimitArg)[0]); args.logical01 = LOGICAL(logical01Arg)[0]; diff --git a/src/froll.c b/src/froll.c index c7e5cfb319..d661f1f520 100644 --- a/src/froll.c +++ b/src/froll.c @@ -65,13 +65,13 @@ void frollmeanFast(double *x, uint64_t nx, ans_t *ans, int k, double fill, bool } w += x[i]; // i==k-1 ans->dbl_v[i] = (double) (w / k); // first full sliding window, non-fill rollfun answer - if (R_FINITE((double) w)) { // proceed only if no NAs detected in first k obs, otherwise early stopping + if (isfinite((double) w)) { // proceed only if no NAs detected in first k obs, otherwise early stopping for (uint64_t i=k; idbl_v[i] = (double) (w / k); // rollfun to answer vector } - if (!R_FINITE((double) w)) { // mark to re-run with NA care + if (!isfinite((double) w)) { // mark to re-run with NA care if (hasna==-1) { // raise warning ans->status = 2; snprintf(end(ans->message[2]), 500, _("%s: hasNA=FALSE used but NA (or other non-finite) value(s) are present in input, use default hasNA=NA to avoid this warning"), __func__); @@ -96,14 +96,14 @@ void frollmeanFast(double *x, uint64_t nx, ans_t *ans, int k, double fill, bool int nc = 0; // NA counter within sliding window int i; // iterator declared here because it is being used after for loop for (i=0; idbl_v[i] = fill; // partial window fill all } - if (R_FINITE(x[i])) { + if (isfinite(x[i])) { w += x[i]; // i==k-1 } else { nc++; @@ -116,12 +116,12 @@ void frollmeanFast(double *x, uint64_t nx, ans_t *ans, int k, double fill, bool ans->dbl_v[i] = narm ? (double) (w / (k - nc)) : NA_REAL; // some values in window are NA } for (uint64_t i=k; idbl_v[i] = (double) w; - if (R_FINITE((double) w)) { + if (isfinite((double) w)) { for (uint64_t i=k; idbl_v[i] = (double) w; } - if (!R_FINITE((double) w)) { + if (!isfinite((double) w)) { if (hasna==-1) { ans->status = 2; snprintf(end(ans->message[2]), 500, _("%s: hasNA=FALSE used but NA (or other non-finite) value(s) are present in input, use default hasNA=NA to avoid this warning"), __func__); @@ -299,14 +299,14 @@ void frollsumFast(double *x, uint64_t nx, ans_t *ans, int k, double fill, bool n int nc = 0; int i; for (i=0; idbl_v[i] = fill; } - if (R_FINITE(x[i])) { + if (isfinite(x[i])) { w += x[i]; } else { nc++; @@ -319,12 +319,12 @@ void frollsumFast(double *x, uint64_t nx, ans_t *ans, int k, double fill, bool n ans->dbl_v[i] = narm ? (double) w : NA_REAL; } for (uint64_t i=k; idbl_v[i] = (double) w; } else { if (!narm) { diff --git a/src/frolladaptive.c b/src/frolladaptive.c index 39485c3560..fbe9e050f9 100644 --- a/src/frolladaptive.c +++ b/src/frolladaptive.c @@ -41,7 +41,7 @@ void fadaptiverollmeanFast(double *x, uint64_t nx, ans_t *ans, int *k, double fi w += x[i]; // cumulate in long double cs[i] = (double) w; } - if (R_FINITE((double) w)) { // no need to calc this if NAs detected as will re-calc all below in truehasna==1 + if (isfinite((double) w)) { // no need to calc this if NAs detected as will re-calc all below in truehasna==1 #pragma omp parallel for num_threads(getDTthreads(nx, true)) for (uint64_t i=0; idbl_v[i] = (double) w; } else { if (!narm) { diff --git a/src/utils.c b/src/utils.c index 993b4edafa..1823421adf 100644 --- a/src/utils.c +++ b/src/utils.c @@ -4,11 +4,11 @@ bool within_int32_repres(double x) { // N.B. (int)2147483647.99 is not undefined behaviour since s 6.3.1.4 of the C // standard states that behaviour is undefined only if the integral part of a // finite value of standard floating type cannot be represented. - return R_FINITE(x) && x < 2147483648 && x > -2147483648; + return isfinite(x) && x < 2147483648 && x > -2147483648; } bool within_int64_repres(double x) { - return R_FINITE(x) && x <= (double)INT64_MAX && x >= (double)INT64_MIN; + return isfinite(x) && x <= (double)INT64_MAX && x >= (double)INT64_MIN; } // used to error if not passed type double but this needed extra is.double() calls in calling R code