2016-04-23 25 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)