将两个整数的乘积除以它们的 gcd 的结果不正确
Posted
技术标签:
【中文标题】将两个整数的乘积除以它们的 gcd 的结果不正确【英文标题】:Incorrect result of dividing the product of two integers by their 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 【参考方案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
而不是自己实现。
【讨论】:
以上是关于将两个整数的乘积除以它们的 gcd 的结果不正确的主要内容,如果未能解决你的问题,请参考以下文章