可能重复: Fastest方法来确定是否一个整数的平方根是一个整数
什么是方法,如果一个号码是完美的正方形?
布尔IsPerfectSquare(长的输入)
{
// 去做
}
我使用C#,但这是语言无关。
奖励积分的清晰度和简洁性(这并不意味着是code高尔夫球场)。
编辑::此得到了更复杂的比我预想的!原来的问题,双precision体现出来几个方面。首先,需要的Math.sqrt双重不能precisely持有长(感谢乔恩)。
二,双重的precision将失去小的值(.000 ... 00001)当你有一个巨大的,接近完美的正方形。例如,我实现Math.Pow失败这个测试(10,18)+1(我的报道属实)。
解决方案布尔IsPerfectSquare(长的输入)
{
长closestRoot =(长)的Math.sqrt(输入);
返回输入== closestRoot * closestRoot;
}
这可能的部分的的只是检查的问题逃脱是平方根的整数,但可能不是全部。你可能需要得到一点点funkier:
布尔IsPerfectSquare(长的输入)
{
双根=的Math.sqrt(输入);
长rootBits = BitConverter.DoubleToInt64Bits(根);
长下界=(长)BitConverter.Int64BitsToDouble(rootBits-1);
长上界=(长)BitConverter.Int64BitsToDouble(rootBits + 1);
为(长候选人=下界;候选LT =上界;候选++)
{
如果(候选*候选人==输入)
{
返回true;
}
}
返回false;
}
恶心,而且不需要什么比真正的大值等,但我认为它的应该的工作...
Possible Duplicate: Fastest way to determine if an integer's square root is an integer
What's a way to see if a number is a perfect square?
bool IsPerfectSquare(long input)
{
// TODO
}
I'm using C# but this is language agnostic.
Bonus points for clarity and simplicity (this isn't meant to be code-golf).
Edit: This got much more complex than I expected! It turns out the problems with double precision manifest themselves a couple ways. First, Math.Sqrt takes a double which can't precisely hold a long (thanks Jon).
Second, a double's precision will lose small values ( .000...00001) when you have a huge, near perfect square. e.g., my implementation failed this test for Math.Pow(10,18)+1 (mine reported true).
解决方案
bool IsPerfectSquare(long input)
{
long closestRoot = (long) Math.Sqrt(input);
return input == closestRoot * closestRoot;
}
This may get away from some of the problems of just checking "is the square root an integer" but possibly not all. You potentially need to get a little bit funkier:
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, and unnecessary for anything other than really large values, but I think it should work...
上一篇:随机加权的选择