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

Mic*_*ren 85 algorithm math perfect-square

可能重复:
确定整数的平方根是否为整数的最快方法

有什么方法可以看出一个数字是否是一个完美的正方形

bool IsPerfectSquare(long input)
{
   // TODO
}
Run Code Online (Sandbox Code Playgroud)

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

奖励点是为了清晰和简洁(这不是代码高尔夫).


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

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

Jon*_*eet 116

bool IsPerfectSquare(long input)
{
    long closestRoot = (long) Math.Sqrt(input);
    return input == closestRoot * closestRoot;
}
Run Code Online (Sandbox Code Playgroud)

这可能会远离一些只是检查"是平方根是一个整数"但可能不是全部的问题.你可能需要更有趣一点:

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;
}
Run Code Online (Sandbox Code Playgroud)

Icky,除了非常大的价值之外没什么其他的东西,但我认为它应该有用......

  • 伙计,你是jon双向飞碟. (187认同)
  • 喜欢我之前得到的赞成数量*将其更正为更加防弹的解决方案;) (26认同)
  • 我认为准确性很重要.否则我会选择"保证随机"的响应:) (17认同)
  • 您不需要防弹解决方案.彻底测试和[有点证明](http://math.stackexchange.com/q/237865/14435). (7认同)
  • @Jon:我正在考虑撤销我的upvote.他要求*清晰*和*简单*.:) (3认同)
  • 您的第一种方法失败的示例输入是什么? (2认同)
  • @Yakk:而我会说第二段代码在能够理解它绝对是正确的方面更简单。这样说吧 - 我发现这里的 *code* 比 maaartinus 在 math.stackexchange 上的帖子中的 *maths* 更容易理解。 (2认同)

Tre*_*reb 12

bool IsPerfectSquare(long input)
{
    long SquareRoot = (long) Math.Sqrt(input);
    return ((SquareRoot * SquareRoot) == input);
}
Run Code Online (Sandbox Code Playgroud)


Sva*_*nte 9

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

(defun perfect-square-p (n)
  (= (expt (isqrt n) 2)
     n))
Run Code Online (Sandbox Code Playgroud)