Ahh, das gute alte integer
gegen double
Division Problem in C++. Bevor wir beginnen, beachten Sie, dass: arma::vec
ist standardmäßig ein double
und 1
, 10
sind 1/10
alle int
s ...
nehmen wir einen Blick auf Ihre Funktionen getrennt:
#include <RcppArmadillo.h>
// [[Rcpp::depends("RcppArmadillo")]]
// [[Rcpp::export]]
arma::vec funtemp_one(arma::vec x)
{
return(x/10); // this works
}
// [[Rcpp::export]]
arma::vec funtemp_two(arma::vec x)
{
return((1/10)*x); // this does not work
}
// [[Rcpp::export]]
arma::vec funtemp_three(arma::vec x)
{
return(x*(1/10)); // this does not work
}
Deshalb, wenn wir laufen über Ihr Problem, das wir erhalten:
> funtemp_one(1)
[,1]
[1,] 0.1
> funtemp_two(1)
[,1]
[1,] 0
> funtemp_three(1)
[,1]
[1,] 0
In den späteren Funktionen (zB die 1/10
), die operator/
, das verwendet wird, ist int
basierte Division. Als Ergebnis wird 2 int
eingegeben und 1 int
zurückgegeben. Wenn das Ergebnis nicht teilbar ist, wird am Ende eine Null zurückgegeben, da sie außerhalb des Ganzzahlbereichs liegt.
Um die Double-Version zu verwenden, die ein Double zurückgibt, muss mindestens einer der int
s explizit in double
umgewandelt werden. Dies geschieht standardmäßig im ersten Fall, da Sie eine double
/int
aufgrund der Struktur arma::vec
haben. Der zweite und dritte Fall hat eine Struktur, die mit int/int
auf zwei Arten behandelt werden kann: 1. ein .0
verwenden, nachdem die int
oder 2. den Wert explizit als Doppel gegossen mit double(int)
z.B.
// [[Rcpp::export]]
arma::vec funtemp_four(arma::vec x)
{
return(x*(1/10.0)); // this works
}
// [[Rcpp::export]]
arma::vec funtemp_five(arma::vec x)
{
return(x*(1/double(10))); // this works
}
geben wird, was Sie erwarten:
> funtemp_four(1)
[,1]
[1,] 0.1
> funtemp_five(1)
[,1]
[1,] 0.1
@Coatless war hier mit seiner Zeit sehr großzügig. Sie sind im Grunde auf ein (lästiges, aber unvermeidliches) Anfängerproblem gestoßen, das jeder C/C++ - Programmierer irgendwann erlebt. Das hat nichts mit Rcpp oder Armadillo per se zu tun. –