一个奇怪的C++错误,也许是相对于长长类型而言的

A strange C++ error, maybe it is relative to the long long type

本文关键字:也许 相对于 类型 C++ 一个 错误      更新时间:2023-10-16

我的代码如下:

#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,但正确答案应该是226436590403296。 看起来输出被切断为 32 位。所以,我打印变量temp_gcd,它是 4.我更改了表达式

long long result = abproduct/temp_gcd;

long long result = abproduct/4;

然后它输出正确答案。

问题出在long long abproduct = a*b;

由于ab都是int的,对它们的任何操作都会导致int,在这种情况下将导致溢出。在执行计算时,尝试将ab转换为long long

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

您正在执行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);

请注意,这不能丢弃信息(不过,一般来说,您必须小心整数除法丢弃信息)。

不想

编辑@MahlerFive的答案 - 这也应该有效。我会把 a 和 b 投到长长的喜欢:long long abproduct = static_cast<long long>(a)*static_cast<long long>(b) .