Ram Patra
Ram Patra

Reputation: 16674

Perfect Java code to determine a Double is a Perfect Square or not?

I want to determine whether a number (in double) is a perfect square or not. I have used the below code but it fails for many inputs.

private static boolean isSquare(double i) {
        double s = Math.sqrt(i);
        return ((s*s) == i);
    }

When s results in scientific form, the code fails. For example when s is 2.719601835756618E9

Upvotes: 0

Views: 1031

Answers (3)

Shivamyadav37
Shivamyadav37

Reputation: 1

static boolean checkPerfectSquare(double x)
{

// finding the square root of given number 
double sq = Math.sqrt(x); 

/* Math.floor() returns closest integer value, for
 * example Math.floor of 984.1 is 984, so if the value
 * of sq is non integer than the below expression would
 * be non-zero.
 */
return ((sq - Math.floor(sq)) == 0); 
} 

Upvotes: 0

Michele
Michele

Reputation: 1274

I know that the question is old, but I would post my solution anyway:

return Math.sqrt(i) % 1d == 0;

Simply check if the sqrt has decimals.

Upvotes: -1

user2357112
user2357112

Reputation: 281528

Your code makes no attempt to test whether the square root of the number is an integer. Any nonnegative real number is the square of some other real number; your code's result depends entirely on floating-point rounding behavior.

Test whether the square root is an integer:

if (Double.isInfinite(i)) {
    return false;
}
sqrt = Math.sqrt(i);
return sqrt == Math.floor(sqrt) && sqrt*sqrt == i;

The sqrt*sqrt == i check should catch some cases where a number exceptionally close to a square has a square root whose closest double approximation is an integer. I have not tested this and make no warranties as to its correctness; if you want your software to be robust, don't just copy the code out of the answer.

UPDATE: Found a failing edge case. If an integer double has a greatest odd factor long enough that the square is not representable, feeding the closest double approximation of the square to this code will result in a false positive. The best fix I can think of at the moment is examing the significand of the square root directly to determine how many bits of precision it would take to represent the square. Who knows what else I've missed, though?

Upvotes: 2

Related Questions