什么是确定输入是否是完美正方形的好算法?

时间:2008-12-05 13:35:31

标签: algorithm math perfect-square

  

可能重复:
  Fastest way to determine if an integer's square root is an integer

有什么方法可以查看数字是perfect square

bool IsPerfectSquare(long input)
{
   // TODO
}

我正在使用C#,但这与语言无关。

明确和简单的奖励点(这不是代码高尔夫)。


编辑:这比我想象的要复杂得多!事实证明,双精度问题有两种表现形式。首先,Math.Sqrt采用了一个不能精确控制的长度(感谢Jon)。

第二,当你拥有一个巨大的近乎完美的正方形时,双精度将会失去很小的值(.000 ... 00001)。例如,我的实现未通过Math.Pow(10,18)+1的测试(我的报告为真)。

3 个答案:

答案 0 :(得分:111)

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,对于除了非常大的值之外的其他任何东西都没有必要,但我认为它应该工作......

答案 1 :(得分:12)

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

答案 2 :(得分:9)

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

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