¿Cómo puedo pasar un valor de NA de Rcpp a R en un vector de 64 bits?
Mi primer enfoque sería:
// [[Rcpp::export]]
Rcpp::NumericVector foo() {
Rcpp::NumericVector res(2);
int64_t val = 1234567890123456789;
std::memcpy(&(res[0]), &(val), sizeof(double));
res[1] = NA_REAL;
res.attr("class") = "integer64";
return res;
}
Pero rinde
#> foo()
integer64
[1] 1234567890123456789 9218868437227407266
Necesito conseguir
#> foo()
integer64
[1] 1234567890123456789 <NA>
NA_REAL
después dememcpy
porque el patrón de bits es en ese punto el de aint64
.NA_real
que se trata su pregunta.sizeof(double)
) ¿verdad? Entoncesres[0]
obtiene 64 bitsval
y luego la configuraciónres[1] = ...
usa los siguientes 64 bits. Estoy de acuerdo con el resultado, pero realmente no sigo tu primer comentario.int64_t
que simplemente está "estacionado" dentro de undouble
vector (también conocido comoNumericVector
). No hay una copia de lógica mágica. Jems está haciendo todo el trabajo duro a mano. Incluyendo mapeo de NAs.int64
y mira lo que hacen.Respuestas:
Muy bien, creo que encontré una respuesta ... (no es hermosa, pero funciona).
Respuesta corta:
lo que resulta en
Respuesta larga
Inspeccionar cómo
bit64
almacena unNA
Creado el 23 de abril de 2020 por el paquete reprex (v0.3.0)
vemos que es a
10000...
. Esto se puede recrearRcpp
conint64_t val = 1ULL << 63;
. ¡Usar enmemcpy()
lugar de una simple asignación con=
asegura que no se cambien bits!fuente
#define
declaración correspondiente para declarar que un patrón de bit (a menudomin
omax
) es el valor de NA.Es realmente mucho, mucho más simple. Tenemos el comportamiento de un
int64
in R ofrecido por (varios) paquetes de complementos, el mejor de los cuales esbit64
darnos lainteger64
clase S3 y el comportamiento asociado.Y define la NA internamente de la siguiente manera:
Y eso es todo lo que hay. R y sus paquetes son el código C más importante,
LLONG_MIN
existe allí y se remonta (casi) hasta los padres fundadores.Hay dos lecciones aquí. La primera es la extensión de IEEE que define NaN e Inf para valores de coma flotante . R en realidad va mucho más allá y agrega
NA
para cada uno de sus tipos . Más o menos en la forma anterior: reservando un patrón de bits particular. (Que, en un caso, es el cumpleaños de uno de los dos creadores originales de R.)El otro es admirar la tonelada métrica de trabajo que Jens hizo con el
bit64
paquete y todas las funciones de conversión y operador requeridas. Convertir sin problemas todos los valores posibles, incluidos NA, NaN, Inf, ... no es tarea fácil.Y es un tema interesante que no mucha gente conoce. Me alegra que hayas hecho la pregunta porque ahora tenemos un registro aquí.
fuente