确定输入是不是是完美正方形的好算法是啥? [复制]

Posted

技术标签:

【中文标题】确定输入是不是是完美正方形的好算法是啥? [复制]【英文标题】:What's a good algorithm to determine if an input is a perfect square? [duplicate]确定输入是否是完美正方形的好算法是什么? [复制] 【发布时间】:2010-09-25 12:34:13 【问题描述】:

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

查看数字是否为perfect square 的方法是什么?

bool IsPerfectSquare(long input)

   // TODO

我使用的是 C#,但这与语言无关。

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


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

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

【问题讨论】:

有一个非常相似的问题。请参考***.com/questions/295579/… 以获得出色的答案。 对于您选择的解决方案,不要忘记预先快速检查是否有负面影响。 是的,我把它放在那里,但为简洁起见将其删除。感谢您指出这一点 你也可以谷歌搜索用于整数平方根的 'lsqrt' 方法。 迈克尔,蜥蜴比尔提出了一个很好的观点,即这只是一个类似的问题,而不是完全相同的问题。我认为这个问题不需要结束。此外,完全平方的问题实际上比看起来要复杂得多,这里的答案做出了很大的贡献。 【参考方案1】:
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;

令人讨厌,除了非常大的值之外,其他任何东西都是不必要的,但我认为它应该工作......

【讨论】:

喜欢我在 将其更正为更安全的解决方案之前获得的赞成票数量;) 老兄,你是乔恩·斯基特。 @Jon:我正在考虑撤销我的投票。他要求清晰简单。 :) 我认为准确性很重要。否则我会选择“保证是随机的”回应:) 不需要你的防弹解决方案。经过详尽测试和sort-of proven。【参考方案2】:
bool IsPerfectSquare(long input)

    long SquareRoot = (long) Math.Sqrt(input);
    return ((SquareRoot * SquareRoot) == input);

【讨论】:

【参考方案3】:

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

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

【讨论】:

嘿。看看***.com/a/343862/31615,我应该补充一点,Common Lisp 有一个“完整的”数字堆栈,所以这只适用于任何非负整数(当然,受工作内存的限制)。跨度> 在 SBCL 上,square 应该是 expt: (defun perfect-square-p (n) (= (expt (isqrt n) 2) n)) @BenSima:实际上,由于标准中没有定义square,因此您需要在任何实现中定义(或替换)它。我编辑答案是为了不产生这种依赖。

以上是关于确定输入是不是是完美正方形的好算法是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

检查一个数字是不是是一个完美的正方形

检查一个数字是不是是一个完美的正方形

如何使用 R 中的 mpfr 包检查一个数字是不是是一个完美的正方形?

如何指定给定数字是不是具有整数平方根? [复制]

找到大约 300 位排列的所有完美正方形

确定用户是不是从手机访问页面最可靠的方法是啥? [复制]