Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 是根算法吗_Python_Python 2.7_Floating Point_Precision - Fatal编程技术网

Python 是根算法吗

Python 是根算法吗,python,python-2.7,floating-point,precision,Python,Python 2.7,Floating Point,Precision,我创建了一个函数来确定一个数字是否是另一个数字的根(不确定这是否是正确的项) def isRoot(n, root): return not math.log(n, root)%1 这在很大程度上是可行的,但我发现我有一个浮点问题。例如,如果我做了isRoot(125,5)我得到False。经过一些故障排除,我发现原因是 >>> math.log(125,5) 3.0000000000000004 即使结果应该是3。所以我的问题是,我应该使用一种不同的算法,一种我不知

我创建了一个函数来确定一个数字是否是另一个数字的根(不确定这是否是正确的项)

def isRoot(n, root):
   return not math.log(n, root)%1
这在很大程度上是可行的,但我发现我有一个浮点问题。例如,如果我做了
isRoot(125,5)
我得到
False
。经过一些故障排除,我发现原因是

>>> math.log(125,5)
3.0000000000000004

即使结果应该是
3
。所以我的问题是,我应该使用一种不同的算法,一种我不知道的算法吗?或者,是否有办法确保无论我使用的数字有多大,该模块都能正常工作?

如果您不介意性能问题,可以查看标准库中的模块。它有任意精度的数字。

函数的工作依赖于一个正好等于0(False)的浮点数。一般来说,在处理浮点数时,应该避免进行相等性测试。相反,最好为差异设置一个可接受的公差水平

请尝试以下方法:

def isRoot(n, root, epsilon=1e-10):
    test = math.log(n, root)%1
    return abs(test - int(round(test))) < epsilon
def isRoot(n,root,epsilon=1e-10):
测试=数学日志(n,根)%1
返回abs(测试-整数(圆形(测试))
这个怎么样:

def isRoot(n, root):
    power = 1
    while root ** power < n:
        power += 1
    return root ** power == n
def isRoot(n,root):
功率=1
当根**功率

如果速度太慢,您还可以进行某种二进制搜索以减少检查次数。

避免此问题的最佳方法是使用另一种完全避免浮点数学的方法

def isRoot(n, root):
    return n <= 1 or (False if n % root != 0 else isRoot(n // root, root))
def isRoot(n,root):

返回n刚好四舍五入为整数并验证:

def isRoot(n, root):
    power = int(round(math.log(n, root)))
    return root ** power == n

也许你在
def isSquare(root,n)上的问题会少一些:
@effralgan这不会做我需要它做的事情…我只是建议了答案所建议的另一种方法。这个问题不能通过更精确地解决。@user2357112是的,我想你是对的。有什么建议吗?@Hoopdady:如果你的输入都是整数,那就用整数数学,比如Alex Hall的实现。如果您的输入可以是浮点数,那么尝试使用浮点数来实现这一点的想法是值得怀疑的。对于浮点输入,最好的选择可能是编写
is_near_root
函数,并在比较中引入公差,类似于pault的建议。记住舍入误差可以是低的也可以是高的。采用绝对值应该可以解释这一点。@MarkRansom只是寻找一个足够接近的数字,一种有效的处理方法?似乎应该有一种更明确的方法来做。不,取绝对值不会改变任何事情,
%1
的结果将始终是范围
[0,1)
@Hoopdady是的,这是一个有效的方法,只是这个答案还不是100%正确。当你的数字足够大时,
log
即使不是根也在你的允许范围内,它就会失败。啊,是的,你绝对正确@MarkRansom。我现在意识到绝对值在这里实际上没有任何作用,就像
math.log()
对于负数有一个域错误。您的上述方法要好得多,而且它对负数有效。我真的在寻找一个一次检查的解决方案。我已经找到了,我只需要它更精确。我当然不想要
isRoot(0.5,3)
是真的。@Alexall肯定不是。我假设输入总是大于1的整数。