给出以下基本代码:
double x = 3;
return x *-1;
我希望返回结果为-3。但是,我得到的实际值大约是 1.844674e + 19 (受输出限制)或一个疯狂的大数字。简单地return -x;
也行不通。
更改代码:
double x = 3;
return x *-1.0;
返回正确的输出。 这似乎是一些整数与双精度或布尔值问题。 我知道在不将整数显式地划分为整数的情况下将整数除可以给出0而不是分数,但是我从未见过它会导致乘法或加法问题。
有人能告诉我发生了什么事或指向行为解释以及如何处理吗?
编辑:这是我机器上的可验证示例。
功能:
// [[Rcpp::export]]
double test1(double data)
{
std::vector<double> testArray(data);
return (testArray.size()*-1);
}
从R运行:
test1(4)
结果:
[1] 1.844674e+19
我能够将问题缩小到向量的大小。因此,对于任何正整数大小,.size()函数乘以-1都会得出疯狂的值。乘以-1.0可以很好地工作。
编辑2:我想我明白了。 Toby是正确的,它是一个无符号值,不会转换为double。 在我的原始样本中:
// [[Rcpp::export]]
double test1(double data)
{
std::vector<double> testArray(data);
double arraySize = testArray.size();
return (arraySize*-1);
}
先将其转换为双精度并乘以-1.0即可,效果也很好。
答案 0 :(得分:1)
尽管您认为自己的代码与此类似:
#include <iostream>
double f()
{
double x = 3;
return x * -1;
}
int main()
{
std::cout << f() << std::endl;
}
您实际上拥有的代码从向量x
的结果中提取size()
的类型-这将返回std::size_t
:
#include <cstdint>
#include <iostream>
double f()
{
std::size_t x = 3;
return x * -1;
}
int main()
{
std::cout << f() << std::endl;
}
这里发生的是将std::size_t
乘以int
。当一个论点被签名而一个未签名时的晋升规则表明(来源:CppReference)
如果无符号操作数的转换等级大于或等于有符号操作数的转换等级,则将有符号操作数转换为无符号操作数的类型。
std::size_t
的排名通常高于int
,因此我们现在将3乘以(std::size_t)-1
-这是一个很大的数字。然后,当我们return
时,这个大数字将转换为double
以匹配f()
的签名。
可以通过几种方法避免该问题:
size()
的结果存储到有符号或浮点类型的变量中,并使用它进行乘法。size()
将static_cast<>
的结果转换为有符号或浮点类型。-1.0
)-这将导致另一个参数提升为浮点。