Como posso passar um valor de NA de Rcpp para R em um vetor de 64 bits?
Minha primeira abordagem seria:
// [[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;
}
Mas produz
#> foo()
integer64
[1] 1234567890123456789 9218868437227407266
Eu preciso pegar
#> foo()
integer64
[1] 1234567890123456789 <NA>
NA_REAL
após omemcpy
porque o padrão de bits é nesse ponto o de aint64
.NA_real
que sua questão não é.sizeof(double)
), certo? Entãores[0]
obtém 64 bitsval
e a configuraçãores[1] = ...
usa os próximos 64 bits. Concordo com o resultado, mas não siga o seu primeiro comentário.int64_t
que é meramente "estacionado" dentro de umdouble
vetor (akaNumericVector
). Não há cópia lógica mágica. Jems está fazendo todo o trabalho duro à mão. Incluindo o mapeamento de NAs.int64
e veja o que eles fazem.Respostas:
Tudo bem, acho que encontrei uma resposta ... (não bonita, mas funcionando).
Resposta curta:
o que resulta em
Resposta mais longa
Inspecionando como
bit64
armazena umNA
Criado em 2020-04-23 pelo pacote reprex (v0.3.0)
nós vemos que é um
10000...
. Isso pode ser recriadoRcpp
comint64_t val = 1ULL << 63;
. Usar emmemcpy()
vez de uma atribuição simples=
garante que nenhum bit seja alterado!fonte
#define
instrução correspondente para declarar um padrão de bit (geralmente ummin
ou outromax
) como o valor NA.É realmente muito, muito mais simples. Temos o comportamento de um
int64
em R oferecido por (vários) pacotes complementares, o melhor dos quais estábit64
nos fornecendo ainteger64
classe S3 e o comportamento associado.E define NA internamente da seguinte maneira:
E isso é tudo o que existe. O R e seus pacotes são os principais códigos C, e
LLONG_MIN
existem lá e remontam (quase) até os pais fundadores.Há duas lições aqui. A primeira é a extensão do IEEE que define NaN e Inf para valores de ponto flutuante . R realmente vai muito além e adiciona
NA
para cada um de seus tipos . Quase da maneira acima: reservando um padrão de bits específico. (Que, em um caso, é o aniversário de um dos dois criadores originais do R.)A outra é admirar a tonelada métrica de trabalho que Jens fez com o
bit64
pacote e todas as funções necessárias de conversão e operador. Converter perfeitamente todos os valores possíveis, incluindo NA, NaN, Inf, ... não é uma tarefa fácil.E é um tópico interessante que poucas pessoas sabem. Fico feliz que você fez a pergunta, porque agora temos um registro aqui.
fonte