区分 python 中的大整数和近整数
Distinguishing large integers from near integers in python
我想避免我的代码将近似整数误认为整数。例如,58106601358565889 的平方根为 241,053,109.00000001659385359763188,但是当我使用以下布尔测试时,58106601358565889 让我误以为它是一个完美的平方:
a = 58106601358565889
b = math.sqrt(a)
print(b == int(b))
精度不一定是问题,因为如果我重新检查,我会得到正确的(错误的)结论:
print(a == b**2)
有什么方法可以更好地测试真整数与近似整数? math.sqrt 隐藏在我的代码中的另一个定义中,如果可能的话,我想避免插入对平方根的检查。如果这不是一个好问题,我深表歉意;我是 python.
的新手
问题不在于 int
的精度 - 这是浮点数的有限精度
>>> import math
>>> math.sqrt(58106601358565889)
241053109.0
>>> math.sqrt(58106601358565889) - 241053109
0.0
我认为双重检查是显而易见的解决方案
这不是区分整数和非整数的问题,因为 b
确实是一个整数*。 Python 浮点数的精度不足以将 a
的平方根表示为足够的数字以获得其任何小数部分。您进行的第二次检查:
print(a == b**2)
只打印 False
因为虽然 b
是一个整数,但 b**2
仍然不是 a
.
如果您想测试非常大的整数是否是精确平方,请考虑自己实现平方根算法。
*如小数部分0,而不是isinstance(b, int)
。
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
您还可以查看 gmpy2 库。它具有计算整数平方根和整数平方根加余数的功能。没有精度限制。
>>> import gmpy2
>>> gmpy2.isqrt(58106601358565889)
mpz(241053109)
>>> gmpy2.isqrt_rem(58106601358565889)
(mpz(241053109), mpz(8))
>>>
免责声明:我维护gmpy2
。
我想避免我的代码将近似整数误认为整数。例如,58106601358565889 的平方根为 241,053,109.00000001659385359763188,但是当我使用以下布尔测试时,58106601358565889 让我误以为它是一个完美的平方:
a = 58106601358565889
b = math.sqrt(a)
print(b == int(b))
精度不一定是问题,因为如果我重新检查,我会得到正确的(错误的)结论:
print(a == b**2)
有什么方法可以更好地测试真整数与近似整数? math.sqrt 隐藏在我的代码中的另一个定义中,如果可能的话,我想避免插入对平方根的检查。如果这不是一个好问题,我深表歉意;我是 python.
的新手问题不在于 int
的精度 - 这是浮点数的有限精度
>>> import math
>>> math.sqrt(58106601358565889)
241053109.0
>>> math.sqrt(58106601358565889) - 241053109
0.0
我认为双重检查是显而易见的解决方案
这不是区分整数和非整数的问题,因为 b
确实是一个整数*。 Python 浮点数的精度不足以将 a
的平方根表示为足够的数字以获得其任何小数部分。您进行的第二次检查:
print(a == b**2)
只打印 False
因为虽然 b
是一个整数,但 b**2
仍然不是 a
.
如果您想测试非常大的整数是否是精确平方,请考虑自己实现平方根算法。
*如小数部分0,而不是isinstance(b, int)
。
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
您还可以查看 gmpy2 库。它具有计算整数平方根和整数平方根加余数的功能。没有精度限制。
>>> import gmpy2
>>> gmpy2.isqrt(58106601358565889)
mpz(241053109)
>>> gmpy2.isqrt_rem(58106601358565889)
(mpz(241053109), mpz(8))
>>>
免责声明:我维护gmpy2
。