当两个大正数相乘时,Rcpp返回大负数

当两个大正数相乘时,Rcpp返回大负数,r,rcpp,R,Rcpp,我正在创建一个函数来计算曲线下的面积,当我取两个部分并将它们乘以分子时,我会超过2^31,然后在计算中使用类似-2013386137的值 下面是cpp块 #include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] NumericVector sort_rcpp(NumericVector x) { std::vector<double> tmp = Rcpp::as< std::vector<

我正在创建一个函数来计算曲线下的面积,当我取两个部分并将它们乘以分子时,我会超过
2^31
,然后在计算中使用类似
-2013386137
的值

下面是cpp块

#include <Rcpp.h>
using namespace Rcpp;


// [[Rcpp::export]]
NumericVector sort_rcpp(NumericVector x) {
  std::vector<double> tmp = Rcpp::as< std::vector<double> > (x);
  std::sort(tmp.begin(), tmp.end());
  return wrap(tmp);
}

// [[Rcpp::export]]
IntegerVector rank(NumericVector x) {
  return match(x, sort_rcpp(x));
}

// [[Rcpp::export]]
double auc_(NumericVector actual, NumericVector predicted) {

  double n = actual.size();

  IntegerVector Ranks = rank(predicted);
  int NPos = sum(actual == 1);
  int NNeg = (actual.size() - NPos);

  int sumranks = 0;

  for(int i = 0; i < n; ++i) {
    if (actual[i] == 1){
      sumranks = sumranks + Ranks[i];
    }
  }

  double p1 = (sumranks - NPos*( NPos + 1 ) / 2);
  long double p2 = NPos*NNeg;

  double auc =  p1 / p2;
  return auc ;

}
我也把它放在一个R包里

devtools::install_github("JackStat/ModelMetrics")

N = 100000
Actual = as.numeric(runif(N) > .65)
Predicted = as.numeric(runif(N))

actual = Actual
predicted = Predicted

ModelMetrics::auc(Actual, Predicted)

在函数内部使用
int
,会导致溢出。使用
double
,事情看起来更阳光明媚:

R> sourceCpp("/tmp/jackstat.cpp")

R> N <- 100000

R> Actual <- as.numeric(runif(N) > .65)

R> Predicted <- as.numeric(runif(N))

R> auc1(Actual, Predicted)   # your function
[1] -0.558932

R> auc2(Actual, Predicted)   # my variant using double
[1] 0.499922
R> 
R>sourceCpp(“/tmp/jackstat.cpp”)
R> N实际(第65段)
R> 预测auc1(实际,预测)#您的函数
[1] -0.558932
R> auc2(实际、预测)#我的变量使用双精度
[1] 0.499922
R>
完整的更正文件如下:

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector sort_rcpp(NumericVector x) {
  std::vector<double> tmp = Rcpp::as< std::vector<double> > (x);
  std::sort(tmp.begin(), tmp.end());
  return wrap(tmp);
}

// [[Rcpp::export]]
IntegerVector rank(NumericVector x) {
  return match(x, sort_rcpp(x));
}

// [[Rcpp::export]]
double auc1(NumericVector actual, NumericVector predicted) {

  double n = actual.size();

  IntegerVector Ranks = rank(predicted);
  int NPos = sum(actual == 1);
  int NNeg = (actual.size() - NPos);

  int sumranks = 0;

  for(int i = 0; i < n; ++i) {
    if (actual[i] == 1){
      sumranks = sumranks + Ranks[i];
    }
  }

  double p1 = (sumranks - NPos*( NPos + 1 ) / 2);
  long double p2 = NPos*NNeg;

  double auc =  p1 / p2;
  return auc ;

}

// [[Rcpp::export]]
double auc2(NumericVector actual, NumericVector predicted) {

  double n = actual.size();

  IntegerVector Ranks = rank(predicted);
  double NPos = sum(actual == 1);
  double NNeg = (actual.size() - NPos);

  double sumranks = 0;

  for(int i = 0; i < n; ++i) {
    if (actual[i] == 1){
      sumranks = sumranks + Ranks[i];
    }
  }

  double p1 = (sumranks - NPos*( NPos + 1 ) / 2);
  long double p2 = NPos*NNeg;

  double auc =  p1 / p2;
  return auc ;

}

/*** R
N <- 100000
Actual <- as.numeric(runif(N) > .65)
Predicted <- as.numeric(runif(N))

auc1(Actual, Predicted)
auc2(Actual, Predicted)
*/
#包括
使用名称空间Rcpp;
//[[Rcpp::导出]]
数字向量排序\u rcpp(数字向量x){
std::vector tmp=Rcpp::as(x);
std::sort(tmp.begin(),tmp.end());
返回包装(tmp);
}
//[[Rcpp::导出]]
积分向量秩(数值向量x){
返回匹配(x,sort_rcpp(x));
}
//[[Rcpp::导出]]
双auc1(实际数值向量、预测数值向量){
double n=实际的.size();
积分因子秩=秩(预测);
int NPos=总和(实际值==1);
int NNeg=(实际的.size()-NPos);
int-sum=0;
对于(int i=0;iN在函数内部使用
int
,这会导致溢出。使用
double
,事情看起来更阳光明媚:

R> sourceCpp("/tmp/jackstat.cpp")

R> N <- 100000

R> Actual <- as.numeric(runif(N) > .65)

R> Predicted <- as.numeric(runif(N))

R> auc1(Actual, Predicted)   # your function
[1] -0.558932

R> auc2(Actual, Predicted)   # my variant using double
[1] 0.499922
R> 
R>sourceCpp(“/tmp/jackstat.cpp”)
R> N实际(第65段)
R> 预测auc1(实际,预测)#您的函数
[1] -0.558932
R> auc2(实际、预测)#我的变量使用双精度
[1] 0.499922
R>
完整的更正文件如下:

#include <Rcpp.h>

using namespace Rcpp;

// [[Rcpp::export]]
NumericVector sort_rcpp(NumericVector x) {
  std::vector<double> tmp = Rcpp::as< std::vector<double> > (x);
  std::sort(tmp.begin(), tmp.end());
  return wrap(tmp);
}

// [[Rcpp::export]]
IntegerVector rank(NumericVector x) {
  return match(x, sort_rcpp(x));
}

// [[Rcpp::export]]
double auc1(NumericVector actual, NumericVector predicted) {

  double n = actual.size();

  IntegerVector Ranks = rank(predicted);
  int NPos = sum(actual == 1);
  int NNeg = (actual.size() - NPos);

  int sumranks = 0;

  for(int i = 0; i < n; ++i) {
    if (actual[i] == 1){
      sumranks = sumranks + Ranks[i];
    }
  }

  double p1 = (sumranks - NPos*( NPos + 1 ) / 2);
  long double p2 = NPos*NNeg;

  double auc =  p1 / p2;
  return auc ;

}

// [[Rcpp::export]]
double auc2(NumericVector actual, NumericVector predicted) {

  double n = actual.size();

  IntegerVector Ranks = rank(predicted);
  double NPos = sum(actual == 1);
  double NNeg = (actual.size() - NPos);

  double sumranks = 0;

  for(int i = 0; i < n; ++i) {
    if (actual[i] == 1){
      sumranks = sumranks + Ranks[i];
    }
  }

  double p1 = (sumranks - NPos*( NPos + 1 ) / 2);
  long double p2 = NPos*NNeg;

  double auc =  p1 / p2;
  return auc ;

}

/*** R
N <- 100000
Actual <- as.numeric(runif(N) > .65)
Predicted <- as.numeric(runif(N))

auc1(Actual, Predicted)
auc2(Actual, Predicted)
*/
#包括
使用名称空间Rcpp;
//[[Rcpp::导出]]
数字向量排序\u rcpp(数字向量x){
std::vector tmp=Rcpp::as(x);
std::sort(tmp.begin(),tmp.end());
返回包装(tmp);
}
//[[Rcpp::导出]]
积分向量秩(数值向量x){
返回匹配(x,sort_rcpp(x));
}
//[[Rcpp::导出]]
双auc1(实际数值向量、预测数值向量){
double n=实际的.size();
积分因子秩=秩(预测);
int NPos=总和(实际值==1);
int NNeg=(实际的.size()-NPos);
int-sum=0;
对于(int i=0;i德克,你太棒了!总是一件愉快的事。这是一个很容易解决的问题,但有时我们都会戴上眼罩。在那里,做了…我正在构建包,学习如何使用Rcpp和C++一般,所以它对我来说都是新的:Dirk,你真棒!总是一件愉快的事。这是一个很容易解决的问题,但有时我们都会戴上眼罩。在那里,做了…我正在构建包,学习如何使用Rcpp和C++一般,所以它对我来说都是新的: