2011-08-14 43 views
2

我寫了一個解謎型網站的解決方案。在帶有最新g ++的XCode上,我的代碼編譯得很好。在他們的網站(和鍵盤)上,我的輸出是負面的。有人能幫我理解爲什麼,因爲我誠實地被難住了。輸出負值的C++代碼

#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; 
} 

通常「長N」應該讀1和從標準輸入百萬之間的整數,但我只分配一個值來模擬它。

我已將代碼放在codepad中:http://codepad.org/RpPFuLzX。正如你所看到的,輸出是-596936,而在我的機器上是656502(這是正確的輸出)。究竟發生了什麼?

回答

5

非常可能的罪魁禍首是鍵盤和其他網站在32位系統,其中long是4個字節長(http://codepad.org/W00vCFIN)上進行編譯。在OS X上,所有內容默認爲64位,在這些系統上(但不是Windows),長度爲8個字節。因此,你在某個時候溢出了一個計算。

如果你依賴於特定的整數大小,使用stdint.h

這裏是一個適合的版本,符合您的預期輸出,使用int64_thttp://codepad.org/Owsl3ClR

+0

謝謝,我完全忽略了這一點。最近得到了一個mac,所以我忽略了操作系統的默認設置。 – BlackJack

0

粘貼到Comeau online,我得到:

"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); 
1

爲什麼你得到不同的結果的原因是數據類型像在32位和64位上的處理方式不同。 Mac OS X使用LP64數據模型,其中64位長的64位長和32位長的32位長。如果您分別爲32位和64位構建程序,則會看到不同的結果。

一種流行的解決方案是使用它們指定的比特數,如uint64_t爲大小的無符號整數數據類型64位而不是long根據標準它只是等於或大於詮釋