首页 >Java >java教程 >确定整数的平方根是否为整数的最快方法是什么?

确定整数的平方根是否为整数的最快方法是什么?

Barbara Streisand
Barbara Streisand原创
2024-12-18 20:28:11433浏览

What's the Fastest Way to Determine if the Square Root of an Integer is an Integer?

一种最快地确定一个整数的平方根是否为整数的方法

问题说明

我正在寻找最快的方法来确定一个长整数是否是一个完全平方(即它的平方根是另一个整数):


  1. 我使用内置的 Math.sqrt() 函数完成了它,但我很好奇是否有一种方法可以使用整数域来完成,从而提高速度。

  2. 维护一个查找表是不切实际的(因为有大约 231.5 个整数的平方小于 263)。

以下是我现在完成它的非常简单直接的方法:

public final static boolean isPerfectSquare(long n)<br>{<br>  if (n < 0)</p><pre class="brush:php;toolbar:false">return false;

long tst = (long)(Math.sqrt(n) 0.5);
return tst*tst == n;
}

注意:我在许多 Project Euler 问题中使用了这个函数。因此,以后将不会对这一段代码进行任何维护。并且这种微型优化实际上可以带来差异,因为挑战的一部分是用不到一分钟的时间完成每个算法,而此函数需要在某些问题中被调用数百万次。


我已经尝试了解决这个问题的不同方案:


  • 经过详尽的测试,我发现向 Math.sqrt() 的结果添加 0.5 is 不必要的,至少在我的机器上是这样。

  • 快速反平方根比 Math.sqrt() 快,但对于 n >= 410881 给出了不正确的结果。然而,正如 BobbyShaftoe 所建议的,我们可以为 n < 410881 使用 FISR hack。

  • Newton's 方法比 Math.sqrt() 慢很多。这可能是因为 Math.sqrt() 使用类似于 Newton 方法的东西,但是在硬件中实现,因此比 Java 中的速度快得多。此外,Newton 方法仍然需要使用双精度浮点数。

  • 一种经过改进的 Newton 方法,它利用了一些技巧,使其只需要进行整数运算,在避免溢出时也需要一些技巧(我希望该函数可以处理所有正的 64 位有符号整数),而且它比 Math.sqrt() 慢。

  • 二分查找甚至更慢。这是有道理的,因为二分查找平均需要进行 16 次传递才能找到 64 位数字的平方根。

  • 根据 John 的测试,在 C 中使用或语句比使用开关速度更快,但在 Java 和 C# 中,或和开关之间似乎没有区别。

  • 我还尝试制作一个查找表(作为 64 个布尔值的私有静态数组)。然后,不是使用 switch 或 or 语句,我会直接说 if(lookup[(int)(n&0x3F)]) { test } else return false;. 令我惊讶的是,这(略微)慢了一些。这是因为数组边界在 Java 中是受检的。

以上是确定整数的平方根是否为整数的最快方法是什么?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn