因此,我只是修改了我认为适合自己风格的内容,这是从另一个人对算法的回答中得出的。我决定要更改的一件事,当时根本不感到困惑,是更改了他们在整个计算中放置//
和int()
的所有位置,给了我相同的结果。现在,当我完成所有这些次要细节的更改后,我认为测试用例会通过...我错了。下面的函数应该做同样的事情,如果给定的示例要通过该函数,则它以相同的公分母返回所有给定的分数(例如... [[1, 2], [1, 3], [1, 4]]
的格式)它应该返回[[6, 12], [4, 12], [3, 12]]
。
使用int()
作为返回值(最后一位):
from math import gcd
from functools import reduce
def convertFracts(lst):
if not lst: return []
lcm = lambda a, b: int(a*b / gcd(a, b))
denom_list = (i[1] for i in lst)
lcm_num = reduce(lcm, denom_list)
return [[int(i[0]*lcm_num / i[1]), lcm_num] for i in lst]
使用//
作为返回值(最后一位):
from math import gcd
from functools import reduce
def convertFracts(lst):
if not lst: return []
lcm = lambda a, b: int(a*b / gcd(a, b))
denom_list = (i[1] for i in lst)
lcm_num = reduce(lcm, denom_list)
return [[i[0]*lcm_num // i[1], lcm_num] for i in lst]
使用int()
时失败,但使用//
时通过的测试用例,其中包含非常大的分数:
[[27115, 5262], [87546, 11111111], [43216, 255689]]
这是使用int()
时的结果:
[[77033412951888080, 14949283383840498], [117787497858828, 14949283383840498], [2526695441399712, 14949283383840498]]
但这不等于正确的答案:
[[77033412951888085, 14949283383840498], [117787497858828, 14949283383840498], [2526695441399712, 14949283383840498]]
当使用//
而不是int()
作为返回位时,它通过了...我的问题是,为什么int()
失败了,//
却失败了,大数字会降低精度吗?
答案 0 :(得分:3)
int()
不是问题。问题在于,当用/
除时,结果是float
(这就是为什么需要int()
的原因)。 float
使用固定数量的位数表示该值,因此,如果位数太多,则它们将从数字的最低有效位开始被切除。此外,当位被切掉时,舍入发生。以十六进制形式更容易看到丢失的位。例如:
randomStuff = 0x979182375823975089237584250DEADBEEF
x = randomStuff * 1337
print(hex(int(x / 1337)))
print(hex(x // 1337))
此打印:
0x97918237582398000000000000000000000
0x979182375823975089237584250deadbeef
通过float
,很多位被切断了。
答案 1 :(得分:1)
我也许可以提供帮助。 This site关于下限/整数除法(//)提出以下建议:“结果值是一个整数,尽管结果的类型不一定是int。”有一个长整数类型,可以用较大的数字实现更高的精度。我个人不需要使用它,但是由于您的错误情况与大值有关,因此可能是相关的。
测试使用地板分割的算法的先前版本中的值的类型可能很有趣/很有价值,只是看它们是否变长。我发誓我读过某个地方,Python已经开始自动处理int / long转换,但是通过int()显式转换可能会导致问题。
编辑:我错了,并认为我最初提供的链接与您的问题有关。它实际上来自Python 2.4文档,而针对3.8的更新的语言文档部分没有提及long。如果您使用的是已标记的Python 3.x,恐怕此答案可能无济于事。