Python Perfect Square
## Python: How to Check If a Number is a Perfect Square
A **perfect square** is an integer that can be expressed as the square of another integer. For example, $1$ ($1^2$), $4$ ($2^2$), $9$ ($3^2$), and $16$ ($4^2$) are all perfect squares.
In Python, there are several ways to determine whether a given number is a perfect square. This tutorial covers the most efficient and standard approaches, ranging from built-in mathematical functions to alternative algorithms.
---
## Method 1: Using `math.isqrt()` (Recommended)
Starting from Python 3.8, the `math` module provides the `math.isqrt(n)` function. This function returns the greatest integer $x$ such that $x^2 \le n$. It is highly optimized, handles extremely large integers, and avoids floating-point precision issues.
### Code Example
```python
import math
def is_perfect_square(n: int) -> bool:
# Negative numbers cannot be perfect squares
if n < 0:
return False
# Find the integer square root of n
sqrt_val = math.isqrt(n)
# Check if the square of the integer root equals the original number
return sqrt_val * sqrt_val == n
# Test the function
number = 16
if is_perfect_square(number):
print(f"{number} is a perfect square.")
else:
print(f"{number} is not a perfect square.")
```
### Code Explanation
1. **`import math`**: Imports Python's built-in math module to access advanced mathematical operations.
2. **`if n < 0:`**: Instantly filters out negative numbers, as no real integer squared can result in a negative value.
3. **`sqrt_val = math.isqrt(n)`**: Computes the exact integer square root of `n`. For example, `math.isqrt(16)` returns `4`, and `math.isqrt(17)` also returns `4`.
4. **`return sqrt_val * sqrt_val == n`**: Multiplies the integer root by itself. If the result equals `n`, then `n` is a perfect square.
### Output
```text
16 is a perfect square.
```
---
## Method 2: Using the Exponentiation Operator (`**`)
If you are using an older version of Python (prior to 3.8) or want a quick solution without importing any modules, you can use the exponentiation operator `** 0.5` to find the square root.
### Code Example
```python
def is_perfect_square_exponent(n: int) -> bool:
if n < 0:
return False
# Calculate the square root using float exponentiation
sqrt_val = n ** 0.5
# Check if the square root is an integer
return sqrt_val.is_integer()
# Test the function
number = 25
print(f"Is {number} a perfect square? {is_perfect_square_exponent(number)}")
```
### Considerations for Method 2
* **`is_integer()`**: This float method returns `True` if the float instance is finite and has a fractional part equal to zero.
* **Floating-Point Precision**: Because this method converts the number to a float, it can suffer from precision limitations when dealing with extremely large integers (typically numbers greater than $2^{53}$). For large-scale applications, **Method 1** is much safer.
---
## Method 3: Binary Search (No Imports)
If you want to implement the logic from scratch without relying on float arithmetic or built-in square root functions, a binary search algorithm is an elegant and highly efficient $O(\log n)$ solution.
### Code Example
```python
def is_perfect_square_binary(n: int) -> bool:
if n < 0:
return False
if n in (0, 1):
return True
low, high = 1, n // 2
while low <= high:
mid = (low + high) // 2
square = mid * mid
if square == n:
return True
elif square < n:
low = mid + 1
else:
high = mid - 1
return False
# Test the function
number = 100
print(f"Is {number} a perfect square? {is_perfect_square_binary(number)}")
```
---
## Summary of Methods
| Method | Complexity | Best Used For | Pros/Cons |
| :--- | :--- | :--- | :--- |
| **`math.isqrt()`** | $O(\log n)$ | General use (Python 3.8+) | **Recommended**. Fast, precise, handles large numbers perfectly. |
| **`n ** 0.5`** | $O(1)$ | Quick checks on small numbers | Simple syntax, but prone to floating-point precision errors on large integers. |
| **Binary Search** | $O(\log n)$ | Interviews / Custom constraints | No external imports, works purely with integer arithmetic. |
YouTip