函数返回负值

Function Returning Negative Value

本文关键字:返回 函数      更新时间:2023-10-16

我仍然没有通过足够的测试运行它,但由于某些原因,使用某些非负值,该函数有时会返回负值。我在计算器中用不同的值做了很多手动测试,但我还没有让它显示出同样的行为。

我想知道是否有人会看一眼,看看我是否遗漏了什么。

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 之间

pER和:在1.0f和5500.0f之间,然后乘以0.001f,然后传递给上的函数

编辑:

好吧,所以在更仔细地执行之后,这不是这个函数的直接错误。当我稍后使用以下代码时,它会产生一个无限正的浮点值,然后翻转为负:

pPMax=(int)pP存储;

pPStore是一个保存popCalc返回的浮点值。

所以现在的问题是,我该如何阻止公式这样做?即使在Calculator中使用非常高的值进行测试,也从未显示过这种行为。编译器如何处理导致这种情况的操作顺序,或者我的值只是太高了?

在这种情况下,当函数返回后转换回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;
}

正如你在这里看到的,还有其他类型的范围更大。如果这些还不够,我相信最新的增强版本正适合你。

抛出异常:

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周围的值,这个值比32位整数所能容纳的值大一些,所以让我们看看标准对4.9/1:中浮点到整数的转换有什么看法

浮点类型的prvalue可以转换为整数类型。转换集群;即分数部分被丢弃。如果截断的值不能在目的地类型中表示。

因此,我们了解到,对于函数可以生成的大量可能的结果值,返回32位整数的转换是未定义的,这包括生成负数。

这里有几个选项。您可以使用64位整数类型(可能是longlong long)来保存该值,而不是截断为int

或者,您可以将函数的结果缩小约1000倍,以将最大结果保持在32位整数可以保持的值范围内。