A parameter with value of -0 in R becomes 0 in C++ world when using Rcpp. Here is a minimal example that demonstrates this.
library("Rcpp")
cppFunction('
void signCheck(NumericVector v ) {
int vint = Rcpp::as<int>(v);
if (vint < 0) {
Rcout << " v is negative";
}
else if (vint == 0) {
Rcout << "v is zero";
}
else {
Rcout << "v is positive";
}
}
')
a = -0
print(paste("sign in R", sign(1/a)))
signCheck(a)
Here is the output:
[1] "sign in R -1"
v is zero
In short, The difference in -0 and 0 vanishes. Is this a bug? Is there any work around?
There is no bug. The behaviour is as expected: the int
type in C++ (or virtually anywhere else) has no negative zero representation. The distinction between +0 and −0 only exists in IEEE floating point types. The number literal you have in R is a floating point number (to get an integral type, use the L
suffix: 0L
). But your C++ code intentionally converts it to int
and therefore coerces it to 0, dropping the sign information.
Furthermore, your C++ code does not actually check for the sign of the value: the same code in R would also output “v is zero” rather than “v is negative”:
a = -0
if (a < 0) "negative" else if (a == 0) "zero" else "positive"
# [1] "zero"
By contrast, we can verify that C++ does in fact preserve signed 0:
Rcpp::cppFunction("
void signCheck(NumericVector v) {
Rcout << std::signbit(v[0]);
}
")
signCheck(-0)
# 1
(std::signbit
returns true
for negative numbers, which is indicated here by the output 1
.)