确定输入是不是是完美正方形的好算法是啥? [复制]
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
,因此您需要在任何实现中定义(或替换)它。我编辑答案是为了不产生这种依赖。以上是关于确定输入是不是是完美正方形的好算法是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章