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
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
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.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.