Alright, I think I found an answer... (not beautiful, but working).
Short Answer:
// [[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;
}
which results in
#> foo()
integer64
[1] 1234567890123456789 <NA>
Longer Answer
Inspecting how bit64
stores an 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"
Created on 2020-04-23 by the reprex package (v0.3.0)
we see that it is a 10000...
. This can be recreated in Rcpp
with int64_t val = 1ULL << 63;
. Using memcpy()
instead of a simple assign with =
ensures that no bits are changed!
NA_REAL
after thememcpy
because the bit pattern is at that point the one of aint64
. – AspectualNA_real
which is not what your question is about. – Aspectualsizeof(double)
) right? Sores[0]
gets 64 bits fromval
and then settingres[1] = ...
uses the next 64 bits. I agree with the outcome, but don't really follow your first comment. – MuNA_real
uses the same bit pattern that the bit64 package uses (1000...
). I guess I was wrong there. – Muint64_t
that is merely "parked" inside adouble
vector (akaNumericVector
). There is no magic logic copy. Jems is doing all the hard work by hand. Including mapping NAs. – Aspectualstd::memcpy(&(res[1]), &(NA_REAL), sizeof(double));
doesn't work... – Muint64
and see what they do. – Aspectual