Algorithm 提前终止分数指数计算?

Algorithm 提前终止分数指数计算?,algorithm,math,Algorithm,Math,我需要编写一个函数,它取某事物的第六个根(相当于,将某事物提升到1/6次方),并检查答案是否为整数。我希望这个函数尽可能快,尽可能优化,因为这个函数需要大量运行,我认为最好不要计算整个根 在必须计算第六个根的全部内容之前,如何编写返回False(或0或类似内容)的函数(语言不可知,但Python/C/C++更可取)?例如,如果我取65的第6个根,那么我的函数应该在意识到结果不是int时停止计算并返回False,而不是首先计算65的第6个是2.005174515,然后检查2.005174515是否

我需要编写一个函数,它取某事物的第六个根(相当于,将某事物提升到1/6次方),并检查答案是否为整数。我希望这个函数尽可能快,尽可能优化,因为这个函数需要大量运行,我认为最好不要计算整个根

在必须计算第六个根的全部内容之前,如何编写返回
False
(或
0
或类似内容)的函数(语言不可知,但Python/C/C++更可取)?例如,如果我取65的第6个根,那么我的函数应该在意识到结果不是
int
时停止计算并返回
False
,而不是首先计算65的第6个是2.005174515,然后检查2.005174515是否是
int
,最后返回
False

当然,我问这个问题的印象是,提前终止比完整的计算要快,使用

打印(iInstance(num**(1/6),int))

任何帮助或想法都将不胜感激。我也会对很多分数次幂的答案感兴趣,而不仅仅是x^(1/6)。

这里有一些想法,你可以尝试一下,可能有助于快速消除非六次幂。对于实际的六次方,最终仍然需要计算六次方

检查小箱子 如果你得到的数字有一个合理的小概率(比如少于12位),你可以建立一个小案例表,并对照它进行检查。只有100个小于10*12的六次方。如果您的输入总是更大,那么这个测试没有什么价值,但它仍然是一个非常便宜的测试

消除小素数 任何小的素数因子都必须以6的倍数出现。为了避免过多的试驾,您可以将一些小因素组合起来。 例如,
2*3*5*7*11*13*17*19*23=223092870
,它足够小,可以容纳Python中的单个30位分支,因此使用该模的单个模运算应该很快

因此,给定一个测试编号
n
,计算
g=gcd(n,223092870)
,如果结果不是
1
,检查
n
是否可以被
g**6
整除。如果不是,
n
不是第六次幂,那么您就完成了。如果
n
可被
g**6
整除,则重复
n//g**6

检查模124488的值(例如) 如果执行了上一步,则此时的值不能被任何小于
25
的素数整除。现在,您可以使用精心选择的模数进行模数测试:例如,与
124488=8*9*7*13*19
相对素数的任何六次方都与六个值之一一致
[115625196572872948385111385]
模数
124488
。可以使用更大的模量,但代价是必须检查更多可能的残留物

检查它是否是正方形 任何六次方必须是正方形。由于Python(至少,Python>=3.8)有一个内置的整数平方根函数,速度相当快,因此在计算完整的第六个根之前检查该值是否为平方是有效的。(如果它是一个平方,并且您已经计算了平方根,那么现在您只需要提取一个立方根,而不是第六个根。)

使用浮点运算 如果输入不是太大,比如说90位或更小,并且是六次方,那么浮点算法有合理的机会精确地找到第六个根。然而,Python不能保证power操作的准确性,因此需要进行一些额外的检查,以确保结果在预期范围内。对于较大的输入,浮点运算得到正确结果的可能性较小。
(2**53+1)**6的第六个根不能准确地表示为Python浮点(合理地假设Python的
浮点
类型与IEEE 754 binary64格式相匹配),并且一旦
n
超过308位左右,它就太大了,无法放入浮点

使用整数算术 一旦你用尽了所有的廉价技巧,你就别无选择,只能计算第六根的底,然后将其六次方与原始数字进行比较

下面是一些Python代码,将上面列出的所有技巧组合在一起。您应该针对您的特定用例进行自己的计时,并选择哪些技巧值得保留,哪些应该调整或抛弃。技巧的顺序也很重要

来自数学导入gcd,isqrt
#小于10*12的六次方。
小六次幂={n**6表示范围(100)内的n}
def为六次方(n):
"""
确定正整数n是否为六次方。
如果n是六次方,则返回True,否则返回False。
"""
#健全性检查(与小案例检查冗余)

如果n作为输入必须是整数,则一种可能性是对该输入执行素数分解。那么测试和计算都很容易你关心的数字的典型大小是什么?你在处理千位整数吗?更大?@john:六次方,不是六次方!你有没有考虑过用这个
mpz.iroot
计算整数根并返回精确性指示;在优化的C库中执行此操作可能比在Python级别实现的任何早期拒绝算法都要快;布卢姆过滤器