地板数字大于//时,int()的精度是否较低?

时间:2020-05-21 17:05:09

标签: python python-3.x algorithm

因此,我只是修改了我认为适合自己风格的内容,这是从另一个人对算法的回答中得出的。我决定要更改的一件事,当时根本不感到困惑,是更改了他们在整个计算中放置//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()失败了,//却失败了,大数字会降低精度吗?

2 个答案:

答案 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,恐怕此答案可能无济于事。