2016-07-24 179 views
2

我在Codeforces上解決了Quasi-Binary問題(無所謂),這是我的submission。這是我產生的代碼:在不同編譯器上產生不同輸出的代碼

#include <iostream> 
#include <cmath> 

using namespace std; 

int quasi_binary(int num, int tens) 
{ 
    int res,digit; 

    if(num == 0) 
    { 
     return 0; 
    } 

    digit = num%10; 
    num = num/10; 

    res = quasi_binary(num, tens+1); 

    if(digit) 
    { 
     cout << 1; 
     return ((digit-1)*pow(10,tens)+res); 
    } 
    else 
    { 
     cout << 0; 
     return res; 
    } 
} 

int main() 
{ 
    int n,k=-1,temp,digit; 
    cin >> n; 

    //this loop calculates the value of k,as it needs to be printed first 
    temp=n; 
    while(temp) 
    { 
     digit = temp%10; 
     temp = temp/10; 

     if(digit>k) 
      k=digit; 
    } 
    cout << k << endl; 

    //print those k quasi-numbers 
    while(n) 
    { 
     n = quasi_binary(n,0); 
     cout << " "; 
    } 
    return 0; 
} 

我沒有看到任何可能在不同編譯器上產生未定義行爲的語句。我在適當的地方使用了適當的括號,以避免模棱兩可。仍然存在未定義的行爲。任何人都可以請幫忙找到生成未定義行爲的語句/指令。

輸入

415 

輸出(在線評測) - 不正確

5 
111 101 101 11 11 11 11 11 11 11 11 11 

輸出(我的64位PC與海灣合作委員會上) - 正確

5 
111 101 101 101 1 
+2

'POW(10,十位)' - 如果你有整數指數不要使用'pow'。 [不保證pow會給你正確的結果](http://stackoverflow.com/questions/25678481/why-pown-2-return-24-when-n-5/25678721#25678721)。 – PaulMcKenzie

+1

我不認爲它與架構或編譯器有關。測試數字是否大於零時,請使用完整的條件。即使用'if(num> 0)'而不是'if(num)'。不確定這是否是問題 – smac89

+1

*我沒有看到任何可以在不同編譯器上產生未定義行爲的語句* - 但是您確實有產生浮點值的語句('pow()'),因此您的程序不是保證產生相同的結果。 – PaulMcKenzie

回答

5

爲避免將結果小於數學結果1,請將pow(10, tens)替換爲int(0.5 + pow(10, tens))。或者,編寫你自己的整數冪函數。

E.g.

using Int_noneg = int;  // "Not negative" 

auto int_pow(Int_noneg const x, Int_noneg const exponent) 
    -> int 
{ 
    Int_noneg reverse_bits = 0; 
    Int_noneg n_exponent_bits = 0; 
    for(Int_noneg i = exponent; i != 0; i /= 2) 
    { 
     reverse_bits = 2*reverse_bits + i%2; 
     ++n_exponent_bits; 
    } 

    Int_noneg result = 1; 
    for(Int_noneg i = 0; i < n_exponent_bits; ++i, reverse_bits /= 2) 
    { 
     result *= result; 
     if(reverse_bits % 2 != 0) { result *= x; } 
    } 
    return result; 
}; 
0

再進我的解決方案,我帶着一個團隊,去您在您的文章中引用的網站(並不需要這樣做)。我提交了你發佈的原始代碼,是的,你得到的錯誤。因此,在我在主要評論部分中鏈接到的SO評論中,由於浮點和截斷問題,pow函數確實會導致問題。

爲了解決這個問題,你可以做幾件事情,主要是給出的其他答案。不過,我會給我的解決方案:

unsigned long powTable[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 
          10000000, 100000000, 1000000000 }; 

//... 
return ((digit-1)*powTable[tens]+res); 

,而不是調用的pow功能,具有10個權力簡單的查找表聲明,然後tens被用作索引表。

Live Example

+0

嗯,我看不出這是對'int(0.5 + pow(10,幾十))'的改進,無論是隻需要一次的代碼還是(特別是)更一般的可重用代碼? –

+0

這是一個不使用'pow',而是使用查找表的替代解決方案。從未聲稱這是「更好」,只是一種選擇。 – PaulMcKenzie

相關問題