2016-04-23 50 views
1

我的代碼如下:一個奇怪的C++錯誤,也許它是相對於long long類型

#include <iostream> 
int gcd(int a, int b) { 
    //write your code here 
    if(a==0){ 
    return b; 
    }else if(b==0){ 
    return a; 
    }else if(a>b){ 
    int a_pri=a%b; 
    return gcd(b,a_pri); 
    }else if(a<b){ 
    int b_pri=b%a; 
    return gcd(a,b_pri); 
    }else{ 
    return a; 
    } 
} 
long long lcm(int a, int b) { 
    int temp_gcd = gcd(a,b); 
    long long abproduct = a*b; 
    long long result = abproduct/temp_gcd; 
    return result; 
} 

int main() { 
    int a, b; 
    std::cin >> a >> b; 
    std::cout << lcm(a,b) << std::endl; 
    return 0; 
} 

我想輸出兩個數的最大公倍數。 但我輸入兩個數字14159572 63967072,它輸出一個負數-527892768.But正確的答案應該是226436590403296. 它看起來像輸出被切斷爲32位。 所以,我打印變量temp_gcd,它是4.I改變了表達

long long result = abproduct/temp_gcd; 

long long result = abproduct/4; 

然後,它輸出正確的答案。

+0

建議使用無符號類型來處理所有事情:'%'操作符無論如何都不能與負的右操作數一起使用,所以這會使您獲得更高的精度並避免由於溢出而導致的未定義行爲。也許使用'uintmax_t' –

回答

1

您正在執行int乘法運算,因爲這是操作數的數據類型。更改該數據類型。即,改變

long long lcm(int a, int b) 

long long lcm(long long a, long long b) 

不拿地使用強制類型轉換的建議:鑄造應該永遠是不得已的措施,如發動戰爭(只有在政治家和外交家失敗)。

如果您不更改功能簽名,則可以通過將a*b替換爲1LL*a*b來強制進行轉換。但我不建議在這裏。使用正確的數據類型是正確的選擇。

儘管如此,代碼

long long abproduct = a*b; 
long long result = abproduct/temp_gcd; 

不必要增加的情況下的結果可能會溢出。要減少,

long long result = a*(b/temp_gcd); 

提的是,這不能丟棄信息(一般,不過,你必須要小心整數除法丟棄的信息)。

2

的問題是就行long long abproduct = a*b;

由於ab均爲int,對它們的任何操作將導致int,這將導致在此情況下溢出。在進行計算時,嘗試使用ablong long

long long abproduct = (long long)a * b;

+0

另一種方式是'1LL * a * b' –

0

沒有要編輯的@ MahlerFive的答案 - 應該工作了。我會將a和b投到很長一段時間,例如:long long abproduct = static_cast<long long>(a)*static_cast<long long>(b)