【问题标题】:Incorrect result of dividing the product of two integers by their gcd将两个整数的乘积除以它们的 gcd 的结果不正确
【发布时间】:2018-05-24 20:59:03
【问题描述】:

我们知道对于两个数字“a”和“b”; a & b 的乘积等于 GCD(a,b) 和 LCM (a,b) 的乘积。

所以为了找到两个数字的 LCM,我用 Python 编写了这个算法:

def gcd(a,b):

  if b==0:
     return a
  else:
     a_rem = a%b
     return gcd(b,a_rem)

print(int(a*b/(gcd(a,b)))

现在在检查不同的测试用例时,我发现了这一点:

输入: 226553150 1023473145

我的输出: 46374212988031352

正确的输出: 46374212988031350

我不知道为什么会这样,只有最后一位数字是错误的!!

【问题讨论】:

  • 这些数字超出了浮点数的安全整数限制,是的。因此,与其从 float 转换回来,不如始终坚持 int

标签: python-3.x casting integer-division


【解决方案1】:

看起来您正在使用 Python3。除法'/'进行浮点数计算并将结果作为浮点数返回,这对于大数来说并不精确。这与您的 gcd 功能无关。如果您用更大的数字进行除法,您将失去更多的精度数字。尝试 int(12345678923456789123456789 / 1)

【讨论】:

  • 有什么办法可以避免在计算较大数字时出现这种错误?
  • @AnupamKhandelwal 只要只涉及整数值,您就应该使用整数除法 '\\' 而不是 '\'。
【解决方案2】:

在你的情况下,这是 GCD 每一步的输出

1023473145 226553150
226553150 117260545
117260545 109292605
109292605 7967940
7967940 5709385
5709385 2258555
2258555 1192275
1192275 1066280
1066280 125995
125995 58320
58320 9355
9355 2190
2190 595
595 405
405 190
190 25
25 15
15 10
10 5
5 0

将 GCD 设为 5,用于除法 a * b 并本质上将 float 转换为 int,从而产生差异。

【讨论】:

    【解决方案3】:

    为避免因整数到浮点数的转换而导致精度损失,请使用整数除法// 而不是浮点除法/

    print(a*b//gcd(a,b))  # prints 46374212988031350
    

    轻微优化:由于a和b都被gcd整除,所以先除再乘,所以整数的大小更小。

    print(a*(b//gcd(a,b)))  # prints 46374212988031350
    

    进一步优化:在 Python 3.5+ gcd is built in 所以使用 from math import gcd 而不是自己实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-17
      • 1970-01-01
      相关资源
      最近更新 更多