Question
I want the fastest way to determine whether a long value is a perfect square in Java, meaning its square root is also an integer.
My current implementation uses Math.sqrt():
public static boolean isPerfectSquare(long n) {
if (n < 0) {
return false;
}
long test = (long) (Math.sqrt(n) + 0.5);
return test * test == n;
}
I am wondering whether there is a faster approach that works only in the integer domain, instead of relying on floating-point math.
A full lookup table is not practical because there are too many possible values for long inputs.
This function is called millions of times in performance-sensitive code, such as Project Euler problems, so even small optimizations may matter.
I also tested several alternatives:
Math.sqrt()without adding0.5still seemed correct in my tests.- Fast inverse square root was faster, but it became incorrect for larger values.
- Newton's method was slower than
Math.sqrt(). - Integer-only Newton variants needed overflow workarounds and were still slower.
- Binary search was also slower.
- Small modular pre-checks using
switchor bitwise filtering helped avoid unnecessary square root calls. - A boolean lookup table for small modular checks was slightly slower in Java because of array bounds checking.
So the real underlying question is: what is the most practical and fast way to test whether a Java long is a perfect square, especially when the function is called very frequently?
Short Answer
By the end of this page, you will understand how to check whether a long is a perfect square in Java, why Math.sqrt() is usually the best baseline, how integer-based filtering can speed things up, and what common correctness and overflow issues to avoid.
Concept
A perfect square is a number that can be written as k * k for some integer k.
Examples:
0 = 0 * 01 = 1 * 14 = 2 * 29 = 3 * 316 = 4 * 4
For a Java long, the task is:
- Reject negative numbers immediately.
- Compute a candidate square root.
- Check whether squaring that candidate gives the original number.
The most common practical solution is:
long root = (long) Math.sqrt(n);
return root * root == n;
Sometimes people round instead of truncating:
long root = (long) (Math.sqrt(n) + 0.5);
return root * root == n;
Why this matters:
Mental Model
Think of this as a two-stage security check:
- Front desk screening: quickly reject values that could never be perfect squares.
- Identity verification: compute the square root candidate and confirm it exactly.
For example, many numbers can be rejected just by looking at their last few bits. A square number cannot end with every possible bit pattern.
So instead of asking every number to go through the expensive full check, you first ask:
- “Do you even look like a square?”
If the answer is no, return false immediately.
If yes, then do the more expensive exact verification using Math.sqrt() and multiplication.
This is a common performance pattern in programming:
- cheap filter first
- expensive exact check second
Syntax and Examples
The simplest correct Java approach is:
public static boolean isPerfectSquare(long n) {
if (n < 0) {
return false;
}
long root = (long) Math.sqrt(n);
return root * root == n;
}
How it works
Math.sqrt(n)returns adouble- Casting to
longremoves the decimal part - If
nis a perfect square, thenroot * root == n
Example
System.out.println(isPerfectSquare(16)); // true
System.out.println(isPerfectSquare(15)); // false
System.out.println(isPerfectSquare(0)); // true
System.out.println(isPerfectSquare(-4)); // false
Adding a fast pre-check
Step by Step Execution
Consider this version:
public static boolean isPerfectSquare(long n) {
if (n < 0) {
return false;
}
long root = (long) Math.sqrt(n);
return root * root == n;
}
Now trace it with n = 81.
Step 1
if (n < 0)
81 < 0isfalse- continue
Step 2
long root = (long) Math.sqrt(n);
Math.sqrt(81)gives9.0- cast to
longgives
Real World Use Cases
Perfect square checks are more common than they first appear.
Number theory and coding challenges
- Project Euler problems
- prime-related formulas
- integer sequence generation
- factor pair detection
Geometry and grids
- checking whether an area can form an exact square
- verifying square dimensions in tile or board problems
- detecting integer distances in coordinate problems
Data processing
- validating that a value matches square-based constraints
- checking matrix sizes such as
n x n - converting a flat array length into a square grid
Example:
int cells = 144;
if (isPerfectSquare(cells)) {
int size = (int) Math.sqrt(cells);
System.out.println("Grid is " + size + " x " + size);
}
Game and simulation logic
- square map generation
- board sizing
- validating player-built structures
Performance-sensitive filters
In math-heavy programs, a square test is often used as a gate before doing more expensive work.
Real Codebase Usage
In real projects, developers usually combine this concept with a few common patterns.
1. Guard clauses
Reject impossible cases early:
if (n < 0) {
return false;
}
This keeps the function simple and avoids nested logic.
2. Cheap pre-validation
Use modular or bitwise checks before expensive operations:
int last = (int) (n & 0xF);
if (last != 0 && last != 1 && last != 4 && last != 9) {
return false;
}
This is common in high-throughput code where most inputs fail.
3. Exact verification after approximation
Even if the root comes from floating-point math, the final test should be exact:
long root = (long) Math.sqrt(n);
return root * root == n;
This pattern appears in many algorithms:
- estimate first
Common Mistakes
1. Forgetting negative inputs
Broken code:
public static boolean isPerfectSquare(long n) {
long root = (long) Math.sqrt(n);
return root * root == n;
}
Problem:
Math.sqrt()of a negative number isNaN- casting
NaNtolongdoes not express your intent clearly
Better:
if (n < 0) {
return false;
}
2. Trusting floating-point without exact verification
Broken code:
return Math.sqrt(n) % 1 == 0;
Problem:
- floating-point values can have rounding issues
- equality checks on floating-point results are risky
Comparisons
| Approach | Correct for all long values? | Usually fast in Java? | Notes |
|---|---|---|---|
Math.sqrt() + exact multiply check | Yes | Yes | Best practical baseline |
Math.sqrt() + modular pre-filter | Yes | Often | Good when many inputs are not squares |
| Binary search integer sqrt | Yes | Usually no | More code, many loop iterations |
| Newton's method | Can be | Usually no | Must handle convergence and overflow carefully |
Floating-point integer test like sqrt(n) % 1 == 0 | Risky | Not recommended |
Cheat Sheet
Basic perfect square check
public static boolean isPerfectSquare(long n) {
if (n < 0) return false;
long root = (long) Math.sqrt(n);
return root * root == n;
}
Fast reject using last hex digit
int last = (int) (n & 0xF);
if (last != 0 && last != 1 && last != 4 && last != 9) {
return false;
}
Important rules
- Negative numbers are not perfect squares in the integer domain.
- Always do an exact final check:
root * root == n. - Do not rely on
Math.sqrt(n) % 1 == 0. Math.sqrt()is usually the best baseline in Java.- Pre-filters help when most inputs are non-squares.
Common valid endings for squares
FAQ
Is Math.sqrt() accurate enough for checking perfect squares in Java?
Yes, when you use it only to get a candidate root and then verify with root * root == n.
Do I need to add 0.5 before casting?
Usually no for this pattern. A truncation-based check is commonly sufficient when followed by exact verification.
Why not use Math.sqrt(n) % 1 == 0?
Because floating-point values can have rounding behavior that makes exact decimal-based checks unreliable.
Is there a faster integer-only algorithm than Math.sqrt()?
Sometimes in theory, but in Java Math.sqrt() is often faster in practice because it is highly optimized and may use hardware instructions.
Why does a bitwise pre-check help?
It quickly rejects values that cannot be squares, so you avoid many square root calls.
Can root * root overflow?
With the common pattern using root = (long) Math.sqrt(n), the root is at most about 3037000499, so root * root stays within long range.
Should I use a lookup array for the modular filter?
Mini Project
Description
Build a small Java utility that checks whether numbers in a list are perfect squares. The project demonstrates a practical pattern used in performance-sensitive code: reject impossible inputs quickly, then perform an exact verification. This mirrors real utility methods that are reused in math-heavy programs.
Goal
Create a Java program that tests multiple long values and prints whether each one is a perfect square.
Requirements
- Write a method that accepts a
longand returnstrueif it is a perfect square. - Reject negative numbers immediately.
- Add a quick bitwise filter before calling
Math.sqrt(). - Test the method with a mix of negative numbers, small values, large values, squares, and non-squares.
Keep learning
Related questions
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Choosing a @NotNull Annotation in Java: Validation vs Static Analysis
Learn how Java @NotNull annotations differ, when to use each one, and how to choose between validation, IDE hints, and static analysis tools.
Convert a Java Stack Trace to a String
Learn how to convert a Java exception stack trace to a string using StringWriter and PrintWriter, with examples and common mistakes.