Questions tagged «perfect-square»

30
确定整数的平方根是否为整数的最快方法
我正在寻找确定一个long值是否为完美平方(即其平方根是另一个整数)的最快方法: 通过使用内置Math.sqrt() 函数,我已经完成了简单的方法,但是我想知道是否有一种方法可以通过将自己限制为仅整数域来更快地完成操作。 维护查找表是不切实际的(因为大约有2 31.5个整数,其平方小于2 63)。 这是我现在做的非常简单明了的方法: public final static boolean isPerfectSquare(long n) { if (n < 0) return false; long tst = (long)(Math.sqrt(n) + 0.5); return tst*tst == n; } 注意:我在许多Project Euler问题中都使用了此功能。因此,没有其他人将不得不维护此代码。这种微优化实际上可能会有所作为,因为挑战的一部分是在不到一分钟的时间内完成每种算法,并且在某些问题中,需要数百万次调用此函数。 我已经尝试过不同的解决方案: 经过详尽的测试后,我发现0.5没有必要将Math.sqrt()的结果添加进去,至少在我的机器上没有。 的平方根倒数快速增快,但它给了不正确的结果对于n> = 410881.然而,所建议BobbyShaftoe,我们可以使用对于n <410881的FISR黑客攻击。 牛顿的方法比慢Math.sqrt()。这可能是因为Math.sqrt()使用了类似于牛顿方法的方法,但是是在硬件中实现的,因此它比Java快得多。同样,牛顿法仍然需要使用双精度。 一种经过改进的牛顿方法,其中使用了一些技巧,以便仅涉及整数数学运算,因此需要一些技巧来避免溢出(我希望此函数与所有正的64位带符号整数一起使用),但它仍然比慢Math.sqrt()。 二进制印章甚至更慢。这是有道理的,因为二进制印章平均需要16次通过才能找到64位数字的平方根。 根据John的测试,or在C ++中,使用语句比使用a更快switch,但是在Java和C#中,or和之间似乎没有区别switch。 我还尝试制作一个查找表(作为64个布尔值的私有静态数组)。然后or,我只是说而不是switch或statement if(lookup[(int)(n&0x3F)]) { test } else …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.