如何在64位向量中将Rcpp的NA值传递给R?
我的第一个方法是:
// [[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;
}
但是会产生
#> foo()
integer64
[1] 1234567890123456789 9218868437227407266
我需要得到
#> foo()
integer64
[1] 1234567890123456789 <NA>
好吧,我想我找到了答案...(虽然不漂亮,但是可以工作。)>
// [[Rcpp::export]]
Rcpp::NumericVector foo() {
Rcpp::NumericVector res(2);
int64_t val = 1234567890123456789;
std::memcpy(&(res[0]), &(val), sizeof(double));
# This is the magic:
int64_t v = 1ULL << 63;
std::memcpy(&(res[1]), &(v), sizeof(double));
res.attr("class") = "integer64";
return res;
}
这导致
#> foo() integer64 [1] 1234567890123456789 <NA>
更长的答案
检查bit64
如何存储NA
# the last value is the max value of a 64 bit number a <- bit64::as.integer64(c(1, 2, NA, 9223372036854775807)) a #> integer64 #> [1] 1 2 <NA> <NA> bit64::as.bitstring(a[3]) #> [1] "1000000000000000000000000000000000000000000000000000000000000000" bit64::as.bitstring(a[4]) #> [1] "1000000000000000000000000000000000000000000000000000000000000000"
由reprex package(v0.3.0)在2020-04-23创建
我们看到它是一个10000...
。可以用Rcpp
在int64_t val = 1ULL << 63;
中重新创建。使用memcpy()
而不是使用=
进行简单分配,可以确保没有位被更改!