2016-05-02 14 views
-1

Eine sehr einfache Frage zu RcppArmadillo. Versuch, einen Vektor mit einem Skalar zu multiplizieren und abhängig von kleinen Änderungen in der Syntax unterschiedliche Ergebnisse zu erhalten.RcppArmadillo und C++ Division Ausgabe

Irgendwelche Ideen?

// [[Rcpp::depends("RcppArmadillo")]] 
// [[Rcpp::export]] 
arma::vec funtemp(arma::vec x)    
{ 
    // return(x/10); // this works 
    // return((1/10)*x); // this does not work 
    return(x*(1/10)); // this does not work 
} 
+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. –

Antwort

2

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