功能返回负值

时间:2013-06-30 03:42:32

标签: c++ function floating-point return negative-number

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

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

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返回的浮点数。

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

3 个答案:

答案 0 :(得分:1)

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

正如您在此处所看到的,还有其他类型的范围更大。如果这些还不够,我相信最新的升级版本有just the thing for you

答案 1 :(得分:0)

抛出异常:

if (pPStore > static_cast<float>(INT_MAX)) {
    throw std::overflow_error("exceeds integer size");
} else {
   pPMax = static_cast<int>(pPStore);
}

或使用float而不是int。

答案 2 :(得分:0)

当你将每个项的最大值相乘时,得到一个大约1.42312e+12的值,这个值比一个32位整数可以容纳的大一些,所以让我们看一下标准对浮点到标准的看法整数转换,在4.9/1中:

  

浮点类型的prvalue可以转换为a的prvalue   整数类型。转换转发;也就是说,小数部分   被丢弃了。如果截断值不能,则行为未定义   用目的地类型表示。

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

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

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