Dear list members, my R package dwdradar uses Fortran code with the input parameter integer(KIND=2): https://github.com/brry/dwdradar/blob/master/src/binary_to_num.f90#L20 https://github.com/brry/dwdradar/blob/master/src/binary_to_num.f90#L55 The CRAN team wrote to change that (line breaks added): According to the Fortran standards, numerical values are just an enumeration. What e.g. real(kind=4) means (or even if it is accepted) is implementation dependent. Please change them to something portable. kind(1.0) or kind(1.0d0} are commonly used, as is c_double from iso_c_binding. There are differing(?) answers on stackoverflow that I don't understand: https://stackoverflow.com/a/3170438 With what should I replace the current code? A pointer to relevant info would already be highly appreciated. Thanks ahead, Berry PS: I contacted the original author, but his Fortran skills also do not suffice to solve this issue... PPS: a related issue came up in this list yesterday: https://stat.ethz.ch/pipermail/r-package-devel/2023q3/009514.html
[R-pkg-devel] fortran integer(kind=)
2 messages · Berry Boessenkool, Ivan Krylov
On Thu, 31 Aug 2023 06:52:47 +0000
Berry Boessenkool <berryboessenkool at hotmail.com> wrote:
my R package dwdradar uses Fortran code with the input parameter integer(KIND=2): https://github.com/brry/dwdradar/blob/master/src/binary_to_num.f90#L20 https://github.com/brry/dwdradar/blob/master/src/binary_to_num.f90#L55
The "raw" argument of the Fortran function originates from the "dat" argument to the R function "bin2num", which, in turn, originates from readBin(what = raw()): https://github.com/brry/dwdradar/blob/master/R/bin2num.R#L21-L25 https://github.com/brry/dwdradar/blob/master/R/readRadarFile.R#L51 "Raw" vectors correspond to the C type unsigned char, which you seem to be interpreting as 16-bit integers instead. (This might be a violation of aliasing rules, but the compiler is not in a position to see it, and it's been working for years.) The 16-bit integer type in Fortran can be declared using the iso_c_binding module: use, intrinsic :: iso_c_binding, only: c_int16_t integer(KIND=c_int16_t),DIMENSION(Flength),INTENT(in)::raw There's probably a safer and only slightly less performant way to implement binary_to_num in R: dat <- as.integer(dat) # interpret the bytes as little-endian double-byte integers dat <- dat[seq(1, length(dat), 2)] + 256 * dat[seq(2, length(dat), 2)] # extract the 12-bit data out <- bitwAnd(dat, 4095) # set the missing flag is.na(out) <- as.logical(bitwAnd(dat, bitwShiftL(1, 13))) # set the negative flag out <- -1 * as.logical(bitwAnd(dat, bitwShiftL(1, 14))) # set the clutter flag out[as.logical(bitwAnd(dat, bitwShiftL(1, 15)))] <- clutter
Best regards, Ivan