判断输入是否为完全平方的好算法是什么?

可能的复制品:
确定一个整数的平方根是否是一个整数 的最快方法

如何判断一个数字是否是 完美的正方形

bool IsPerfectSquare(long input)
{
// TODO
}

我使用的是 C # ,但这是语言不可知的。

为清晰和简单性加分(这并不意味着代码高尔夫)。


编辑: 这比我想象的要复杂得多!事实证明,双精度的问题表现在几个方面。首先,数学。Sqrt 拿了一个不能精确持久的双人床(谢谢 Jon)。

其次,当你有一个巨大的、接近完美的正方形时,一个 double 的精度会丢失很小的值(.000... 00001)。例如,我的实现在这次数学测试中失败了。Pow (10,18) + 1(地雷属实)。

45275 次浏览
bool IsPerfectSquare(long input)
{
long closestRoot = (long) Math.Sqrt(input);
return input == closestRoot * closestRoot;
}

This may get away from some of the problems of just checking "is the square root an integer" but possibly not all. You potentially need to get a little bit funkier:

bool IsPerfectSquare(long input)
{
double root = Math.Sqrt(input);


long rootBits = BitConverter.DoubleToInt64Bits(root);
long lowerBound = (long) BitConverter.Int64BitsToDouble(rootBits-1);
long upperBound = (long) BitConverter.Int64BitsToDouble(rootBits+1);


for (long candidate = lowerBound; candidate <= upperBound; candidate++)
{
if (candidate * candidate == input)
{
return true;
}
}
return false;
}

Icky, and unnecessary for anything other than really large values, but I think it should work...

bool IsPerfectSquare(long input)
{
long SquareRoot = (long) Math.Sqrt(input);
return ((SquareRoot * SquareRoot) == input);
}

In Common Lisp, I use the following:

(defun perfect-square-p (n)
(= (expt (isqrt n) 2)
n))