1

我想避免我的代码将接近整数误认为整数。例如,58106601358565889 的平方根为 241,053,109.00000001659385359763188,但是当我使用以下布尔测试时,58106601358565889 欺骗了我,让我认为它是一个完美的平方:

a = 58106601358565889
b = math.sqrt(a)
print(b == int(b))

精度不一定是问题,因为如果我重新检查,我会得到正确的(错误)结论:

print(a == b**2)

测试真整数与接近整数的更好方法是什么?math.sqrt 隐藏在我的代码中的另一个定义中,如果可能的话,我想避免插入平方根检查。如果这不是一个好问题,我深表歉意;我是 python 新手。

4

4 回答 4

1

这不是区分整数和非整数的问题,因为b真的是整数*。Python 浮点数的精度不足以表示足够数字的平方根a来获得它的任何小数部分。您进行的第二次检查:

print(a == b**2)

只打印False因为 whileb是一个整数,b**2但仍然不是a.

如果您想测试非常大的整数是否是精确平方,请考虑自己实现平方根算法。

* 与 0 小数部分一样,而不是isinstance(b, int).

于 2016-04-12T05:09:39.587 回答
1
import numpy as np
import math
from decimal import *

a = 58106601358565889
b = np.sqrt(a)
c = math.sqrt(a)
d = Decimal(58106601358565889).sqrt()


print(d)
print(int(d))

print(c)
print(int(c))

print(b)
print(int(b))

o/p

241053109.0000000165938535976
241053109
241053109.0
241053109
241053109.0
241053109

我会说使用decimal.

预期代码:

from decimal import *
d = Decimal(58106601358565889).sqrt()
print(d == int(d))

o/p

False
于 2016-04-12T05:11:21.737 回答
0

You could also look at the gmpy2 library. It has a function for calculating the integer square root and also the integer square root plus remainder. There are no precision constraints.

>>> import gmpy2
>>> gmpy2.isqrt(58106601358565889)
mpz(241053109)
>>> gmpy2.isqrt_rem(58106601358565889)
(mpz(241053109), mpz(8))
>>> 

Disclaimer: I maintain gmpy2.

于 2016-04-12T13:29:54.850 回答
0

这不是int问题的精度 - 这是浮点数的有限精度

>>> import math
>>> math.sqrt(58106601358565889)
241053109.0
>>> math.sqrt(58106601358565889) - 241053109
0.0

我认为仔细检查将是显而易见的解决方案

于 2016-04-12T05:09:13.867 回答