[英]Function Returning Negative Value
我仍然没有通过足够的测试来运行它,但是由于某些原因,使用某些非负值,此函数有时会传回负值。 我已经用不同的值在计算器中做了很多手动测试,但是我还没有显示同样的行为。
我想知道是否有人看我是否丢失了一些东西。
float calcPop(int popRand1, int popRand2, int popRand3, float pERand, float pSRand)
{
return ((((((23000 * popRand1) * popRand2) * pERand) * pSRand) * popRand3) / 8);
}
变量都包含随机生成的值:
popRand1:介于1到30之间
popRand2:介于10到30之间
popRand3:介于50和100之间
pSRand:1至1000
pERand:介于1.0f和5500.0f之间,然后乘以0.001f,然后传递给上述函数
编辑:
好了,因此在更仔细地执行之后,这并不是直接造成此功能的错误。 它产生一个无限大的正浮点数,当我以后使用此代码时,它会翻转为负数:
pPMax =(int)pPStore;
pPStore是一个浮点数,用于保存popCalc的返回值。
所以现在的问题是,如何阻止公式执行此操作? 即使在计算器中使用非常高的值进行测试也从未显示此行为。 编译器如何处理导致这种情况的操作顺序,或者我的值仅仅是太高了?
在这种情况下,似乎在函数返回后转换回int时,有可能达到int的最大值,我建议您使用可以表示更大范围值的类型。
#include <iostream>
#include <limits>
#include <boost/multiprecision/cpp_int.hpp>
int main(int argc, char* argv[])
{
std::cout << "int min: " << std::numeric_limits<int>::min() << std::endl;
std::cout << "int max: " << std::numeric_limits<int>::max() << std::endl;
std::cout << "long min: " << std::numeric_limits<long>::min() << std::endl;
std::cout << "long max: " << std::numeric_limits<long>::max() << std::endl;
std::cout << "long long min: " << std::numeric_limits<long long>::min() << std::endl;
std::cout << "long long max: " << std::numeric_limits<long long>::max() << std::endl;
boost::multiprecision::cpp_int bigint = 113850000000;
int smallint = 113850000000;
std::cout << bigint << std::endl;
std::cout << smallint << std::endl;
std::cin.get();
return 0;
}
如您所见,还有其他类型的范围更大。 如果这些还不够的话,我相信最新的boost版本就可以满足您的需求 。
引发异常:
if (pPStore > static_cast<float>(INT_MAX)) {
throw std::overflow_error("exceeds integer size");
} else {
pPMax = static_cast<int>(pPStore);
}
或者使用float而不是int。
当将每个项的最大值相乘时,您将得到一个大约1.42312e+12
的值,该值1.42312e+12
32位整数可以容纳的值,因此,让我们看看标准中关于浮点数到整数转换的说明: 4.9/1
:
浮点类型的prvalue可以转换为整数类型的prvalue。 转换过程开始; 即,小数部分被丢弃。 如果无法在目标类型中表示截断的值,则该行为未定义。
因此,我们了解到,对于函数可能生成的大部分可能的结果值,返回到32位整数的转换是不确定的,其中包括产生负数。
您在这里有一些选择。 您可以使用64位整数类型(可能是long
或long long
)来保存值,而不是将其截断为int
。
或者,您可以将函数的结果按比例缩小大约1000倍,以使最大结果保持在32位整数可以容纳的值的范围内。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.