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).
To check the perfectness of your square, you can simply calculate the square root of a given number. If the square root is an integer, your number is the perfect square. Let's calculate the squares of the following numbers: 49 and 53 . √49 = 7 - 7 is an integer → number 49 is a perfect square.
double result = Math. Sqrt(numberToCheck); bool isSquare = result%1 == 0; isSquare should now be true for all squares, and false for all others.
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With