繁体   English   中英

C++ 代码输出负值

[英]C++ code outputting negative values

我为一个拼图类型的网站写了一个解决方案。 在 XCode 和最新的 g++ 上,我的代码编译得很好。 在他们的网站(和键盘)上,我的 output 是否定的。 有人可以帮我理解为什么,因为我真的很难过。

#include <iostream>
#include <cmath>
#include <vector>
#include <map>

using namespace std;

vector<int> getAllPrimes(vector<int> primesArray, int n)
{
    vector<int> numArray (n+1, 1);

    for (int i = 2; i <= n; i++)
    {
        if (numArray[i] == 1)
        {
            primesArray.push_back(i);
            for (int k = i; k <= n; k+= i)
            {
                numArray[k] = 0;
            }
        }
    }

    return primesArray;
}

int main()
{
    long n = 32327;

    if (n == 1)
    {
        printf("%ld\n", n);
        return EXIT_SUCCESS;
    }


    map <int, int> primeMap;
    map <int, int>::iterator itr;
    vector<int> primesArray;

    primesArray = getAllPrimes(primesArray, n);

    while(!primesArray.empty())
    {
        long currPrime = primesArray.back(), curr = currPrime;
        while (currPrime <= n)
        {
            primeMap[curr] += (int)floor(n/currPrime);
            currPrime *= curr;   //multiply currPrime to add another factor of curr. 
        }
        primesArray.pop_back();
    }

    //get the number of divisors of n!
    long numDivisors = 1;
    for (itr=primeMap.begin(); itr != primeMap.end(); itr++)
    {
        numDivisors *= ((*itr).second*2)+1;     //power of each prime + 1, * 2 because you need the number of divisors of the square of n!
        numDivisors = numDivisors % 1000007;
    }

    printf("%ld\n", numDivisors);

    return 0;
}

通常,“long n”应该从标准输入读取 1 到 100 万之间的 integer,但我只是分配了一个值来模拟它。

我已将代码放在键盘中: http://codepad.org/RpPFuLzX 如您所见, output 是-596936 ,而在我的机器上是656502 (这是正确的输出)。 到底发生了什么?

罪魁祸首很可能是 CodePad 和其他站点正在 32 位系统上编译,其中long为 4 字节长( http://codepad.org/W00vCFIN )。 在 OS X 上,一切都默认为 64 位,而在那些系统(但不是 Windows)上,long 是 8 字节长。 因此,您在某个时候溢出了计算。

如果您依赖特定的 integer 大小,请使用stdint.h

这是使用int64_t匹配您预期的 output 的改编版本: http://codepad.org/Owsl3ClR

得到不同结果的原因是像long这样的数据类型在 32 位和 64 位上的处理方式不同。 Mac OS X 使用 LP64 数据 model,其中 long 在 64 位模式下为 64 位长,在 32 位模式下为 32 位长。 如果您分别为 32 位和 64 位构建程序,您将看到不同的结果。

一种流行的解决方案是使用指定位数的数据类型,例如uint64_t用于大小为 64 位的无符号整数,而不是根据标准等于或大于 int 的 long long

在线粘贴到 Comeau ,我得到:

"ComeauTest.c", line 49: error: more than one instance of overloaded function
          "floor" matches the argument list, the choices that match are:
            function "floor(long double)"
            function "floor(float)"
            function "floor(double) C"
            function "std::floor(long double)"
            function "std::floor(float)"
            The argument types that you used are: (long)
              primeMap[curr] += (int)floor(n/currPrime);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM