什么是一个很好的algorithm来确定一个input是一个完美的平方?

可能重复:
最快的方法来确定一个整数的平方根是一个整数

怎么看一个数字是一个完美的广场 ?

bool IsPerfectSquare(long input) { // TODO } 

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

奖金分明确和简单(这不意味着代码高尔夫)。


编辑:这比我预期的要复杂得多! 事实certificate,双精度的问题体现在两个方面。 首先,Math.Sqrt需要一个长度不能精确保持的双倍(感谢Jon)。

其次,当你有一个巨大的,接近完美的平方时,双精度会损失小的值(.000 … 00001)。 例如,我的执行失败Math.Pow(10,18)+1(我的报告是正确的)这个testing。

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

这可能会摆脱一些只是检查“是一个整数的平方根”,但可能不是全部的问题。 你可能需要一点点的乐趣:

 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,除了非常大的价值之外不需要任何东西,但我认为它应该工作…

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

在Common Lisp中,我使用以下内容:

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